Skip to content

Commit a0b5e77

Browse files
committed
Som | Add application console capabilities and instrumentation
1 parent 6696447 commit a0b5e77

14 files changed

+3399
-0
lines changed

README.md

Lines changed: 327 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,327 @@
1+
<div align="center">
2+
<img src="assets/belvedere.jpeg" title="Belvedere" alt="Belvedere Logo">
3+
</div>
4+
5+
# Belvedere
6+
7+
Full-featured library to bootstrap golang applications lightning quick.
8+
9+
- [Features](#features)
10+
- [Development](#development)
11+
- [Installation & usage](#installation--usage)
12+
13+
14+
## Development ##
15+
#### Local Dev Setup ###
16+
Pre-Requisites:
17+
1. Add `$GOPATH/bin` and `$GOROOT/bin` to `$PATH` variable
18+
19+
Run Following Commands to set up local dev environment
20+
1. `make setup` - To download all pre-requisites
21+
2. `make all`
22+
23+
## Features ##
24+
25+
Consider Belvedere as your applications' butler providing the following capabilities:
26+
27+
- Configuration Management
28+
- Basic Application Configurations
29+
- Data Store Connectivity Configurations (Optional)
30+
- PostgreSQL
31+
- MongoDB
32+
- Redis
33+
- Instrumentation Connectivity Configurations (Optional)
34+
- DataDog
35+
- Sentry
36+
- New Relic
37+
- i18N Translation Configurations (Optional)
38+
- Locale based translations
39+
- Instrumentation Support
40+
- StatsD
41+
- HTTP Recorders
42+
- Postgres Query Recorders
43+
- Mongo Query Recorders
44+
- Redis Statement Recorders
45+
- Data Store Connectivity Support
46+
- PostgreSQL
47+
- MongoDB
48+
- Redis
49+
- JSON Formatted Logging - With contextual logging
50+
- Console Based Application Support
51+
- Postgres Migrations Support - Up and Down
52+
- MongoDB Index Creation Support
53+
- Web Server Starter Kit
54+
- Logger and instrumentation wrapping
55+
- Global Panic Recovery
56+
- Graceful server shutdown
57+
58+
## Installation & Usage ##
59+
60+
Install Belvedere with:
61+
62+
```sh
63+
go get -u github.com/isomnath/belvedere
64+
```
65+
66+
Sample usage of configuration package.
67+
68+
#### Configuration Usage
69+
70+
```yaml
71+
# Mandatory Configs
72+
APP_NAME
73+
APP_VERSION
74+
APP_ENVIRONMENT
75+
APP_LOG_LEVEL
76+
77+
# Optional Configs
78+
APP_WEB_PORT
79+
APP_NON_WEB_PORT
80+
APP_HEALTH_CHECK_API_PATH
81+
APP_SWAGGER_ENABLED
82+
APP_SWAGGER_DOCS_DIRECTORY
83+
84+
POSTGRES_HOST
85+
POSTGRES_PORT
86+
POSTGRES_DB_NAME
87+
POSTGRES_USERNAME
88+
POSTGRES_PASSWORD
89+
POSTGRES_POOL_SIZE
90+
POSTGRES_MIGRATIONS_DIRECTORY
91+
92+
MONGO_HOSTS
93+
MONGO_DB_NAME
94+
MONGO_USERNAME
95+
MONGO_PASSWORD
96+
MONGO_POOL_SIZE
97+
MONGO_SOCKET_TIMEOUT
98+
MONGO_CONNECTION_TIMEOUT
99+
100+
REDIS_HOST
101+
REDIS_PORT
102+
REDIS_USERNAME
103+
REDIS_PASSWORD
104+
105+
NEW_RELIC_ENABLED
106+
NEW_RELIC_LICENSE_KEY
107+
108+
SENTRY_ENABLED
109+
SENTRY_DSN
110+
111+
DATA_DOG_ENABLED
112+
DATA_DOG_HOST
113+
DATA_DOG_PORT
114+
DATA_DOG_FLUSH_PERIOD_SECONDS
115+
116+
TRANSLATIONS_ENABLED
117+
TRANSLATIONS_PATH
118+
TRANSLATIONS_WHITELISTED_LOCALES
119+
TRANSLATIONS_DEFAULT_LOCALE
120+
```
121+
122+
```go
123+
package main
124+
125+
import "github.com/isomnath/belvedere/config"
126+
127+
func dummyFunc() {
128+
type CustomConfig struct {
129+
KeyOne int `mapstructure:"KEY_ONE"`
130+
KeyTwo string `mapstructure:"KEY_TWO"`
131+
KeyThree bool `mapstructure:"KEY_THREE"`
132+
KeyFour []string `mapstructure:"KEY_FOUR"`
133+
KeyFive []int `mapstructure:"KEY_FIVE"`
134+
}
135+
var custom CustomConfig
136+
config.LoadBaseConfig() // Load Base Application Config - Mandatory
137+
config.LoadTranslationsConfig() // Load Translation Config - Optional(to support i18N language support)
138+
config.LoadPostgresConfig() // Load PostgresDB Connection Configs - Optional
139+
config.LoadMongoConfig() // Load MongoDB Connection Configs - Optional
140+
config.LoadRedisConfig() // Load Redis Connection Configs - Optional
141+
config.LoadCustomConfig(custom) // Load Custom Connection Configs - Optional
142+
143+
// Get Base Application Configs
144+
config.GetAppName()
145+
config.GetAppVersion()
146+
config.GetAppEnvironment()
147+
config.GetAppWebPort()
148+
config.GetAppHealthCheckAPIPath()
149+
config.GetAppLogLevel()
150+
config.GetAppNonWebPort()
151+
config.GetSwaggerEnabled()
152+
config.GetSwaggerDocsDirectory()
153+
154+
// Get Instrumentation Configs
155+
config.GetDataDogConfig()
156+
config.GetSentryConfig()
157+
config.GetNewRelicConfig()
158+
159+
// Get Data Store Configs
160+
config.GetPostgresConfig()
161+
config.GetMongoConfig()
162+
config.GetRedisConfig()
163+
164+
// Get Translations Configs
165+
config.GetTranslationConfig()
166+
167+
// Get Custom Configs
168+
config.GetCustomConfig()
169+
}
170+
```
171+
172+
#### Logger Usage
173+
174+
```go
175+
package main
176+
177+
import (
178+
"net/http"
179+
180+
"github.com/isomnath/belvedere/log"
181+
)
182+
183+
func dummyFn() {
184+
// Pre-requisite - Load Base Config
185+
log.Setup() //To initialize the logger
186+
187+
format := "prefix %s and suffix %s"
188+
args1 := "args1"
189+
args2 := "args2"
190+
request := http.Request{}
191+
192+
log.Logger.Fatalf(format, args1, args2)
193+
log.Logger.Errorf(format, args1, args2)
194+
log.Logger.Infof(format, args1, args2)
195+
log.Logger.Warnf(format, args1, args2)
196+
197+
log.Logger.HTTPErrorf(&request, format, args1, args2)
198+
log.Logger.HTTPInfof(&request, format, args1, args2)
199+
log.Logger.HTTPWarnf(&request, format, args1, args2)
200+
201+
log.Logger.PostgresErrorf(format, args1, args2)
202+
log.Logger.PostgresInfof(format, args1, args2)
203+
log.Logger.PostgresWarnf(format, args1, args2)
204+
205+
log.Logger.MongoErrorf(format, args1, args2)
206+
log.Logger.MongoInfof(format, args1, args2)
207+
log.Logger.MongoWarnf(format, args1, args2)
208+
209+
log.Logger.RedisErrorf(format, args1, args2)
210+
log.Logger.RedisInfof(format, args1, args2)
211+
log.Logger.RedisWarnf(format, args1, args2)
212+
}
213+
```
214+
215+
#### Data Store Usage
216+
217+
```go
218+
package main
219+
220+
import (
221+
"github.com/isomnath/belvedere/config"
222+
"github.com/isomnath/belvedere/console"
223+
"github.com/isomnath/belvedere/store"
224+
)
225+
226+
func dummyFn() {
227+
config.LoadBaseConfig()
228+
config.LoadPostgresConfig()
229+
config.LoadMongoConfig()
230+
config.LoadRedisConfig()
231+
232+
store.PostgresConnect(config.GetPostgresConfig()) // Connects to Postgres DB server
233+
store.GetPostgresClient() // Returns Postgres Client
234+
store.MongoConnect(config.GetMongoConfig()) // Connects to Mongo DB server
235+
store.GetMongoClient() // Returns Mongo Client
236+
store.RedisConnect(config.GetRedisConfig(), 0) // Connects to Redis server
237+
store.GetRedisClient() // Returns Redis Client
238+
}
239+
240+
241+
```
242+
243+
#### Instrumentation Usage
244+
245+
```go
246+
package main
247+
248+
import (
249+
"errors"
250+
251+
"github.com/isomnath/belvedere/config"
252+
"github.com/isomnath/belvedere/instrumentation"
253+
)
254+
255+
func dummyFn() {
256+
config.LoadBaseConfig()
257+
258+
// Init functions
259+
instrumentation.InitializeDataDogClient(config.GetAppName(), config.GetDataDogConfig())
260+
instrumentation.InitializeSentry(config.GetSentryConfig())
261+
262+
// Get Clients - Use the clients to raise custom metrics
263+
instrumentation.GetDataDogClient()
264+
instrumentation.GetSentryClient()
265+
266+
// Data Dog Wrappers
267+
instrumentation.RecordInboundHTTPStat(200, "/path", "GET", 10.2)
268+
instrumentation.RecordOutboundHTTPStat(200, "/path", "GET", 10.2)
269+
270+
instrumentation.RecordPostgresSuccessStat("public", "test_table", "GET_RECORD", 3.2)
271+
instrumentation.RecordPostgresErrorStat("public", "test_table", "GET_RECORD", 3.2)
272+
273+
instrumentation.RecordMongoSuccessStat("test_collection", "INSERT_RECORD", 1.2)
274+
instrumentation.RecordMongoErrorStat("test_collection", "INSERT_RECORD", 1.2)
275+
276+
instrumentation.RecordRedisSuccessStat(0, "SET_KEY", 1.2)
277+
instrumentation.RecordRedisErrorStat(0, "SET_KEY", 1.2)
278+
279+
// Sentry Wrappers
280+
instrumentation.CaptureError(errors.New("some error"))
281+
instrumentation.CaptureErrorWithTags(errors.New("some error"), map[string]string{"tag_1": "value_1"})
282+
instrumentation.CaptureWarn(errors.New("some error"))
283+
}
284+
```
285+
286+
#### Instrumentation Usage
287+
288+
```go
289+
package main
290+
291+
import (
292+
"errors"
293+
294+
"github.com/isomnath/belvedere/config"
295+
"github.com/isomnath/belvedere/instrumentation"
296+
)
297+
298+
func dummyFn() {
299+
config.LoadBaseConfig()
300+
301+
// Init functions
302+
instrumentation.InitializeDataDogClient(config.GetAppName(), config.GetDataDogConfig())
303+
instrumentation.InitializeSentry(config.GetSentryConfig())
304+
305+
// Get Clients - Use the clients to raise custom metrics
306+
instrumentation.GetDataDogClient()
307+
instrumentation.GetSentryClient()
308+
309+
// Data Dog Wrappers
310+
instrumentation.RecordInboundHTTPStat(200, "/path", "GET", 10.2)
311+
instrumentation.RecordOutboundHTTPStat(200, "/path", "GET", 10.2)
312+
313+
instrumentation.RecordPostgresSuccessStat("public", "test_table", "GET_RECORD", 3.2)
314+
instrumentation.RecordPostgresErrorStat("public", "test_table", "GET_RECORD", 3.2)
315+
316+
instrumentation.RecordMongoSuccessStat("test_collection", "INSERT_RECORD", 1.2)
317+
instrumentation.RecordMongoErrorStat("test_collection", "INSERT_RECORD", 1.2)
318+
319+
instrumentation.RecordRedisSuccessStat(0, "SET_KEY", 1.2)
320+
instrumentation.RecordRedisErrorStat(0, "SET_KEY", 1.2)
321+
322+
// Sentry Wrappers
323+
instrumentation.CaptureError(errors.New("some error"))
324+
instrumentation.CaptureErrorWithTags(errors.New("some error"), map[string]string{"tag_1": "value_1"})
325+
instrumentation.CaptureWarn(errors.New("some error"))
326+
}
327+
```

assets/belvedere.jpeg

43.4 KB
Loading

console/mongo_indexes.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package console
2+
3+
import (
4+
"context"
5+
"strings"
6+
7+
"github.com/isomnath/belvedere/config"
8+
"github.com/isomnath/belvedere/log"
9+
"github.com/isomnath/belvedere/store"
10+
11+
"go.mongodb.org/mongo-driver/mongo"
12+
)
13+
14+
// CreateIndexes - Allows creating mongoDB indexes
15+
// Ideally to be used as console command
16+
func CreateIndexes(collectionName string, models []mongo.IndexModel) error {
17+
ctx := context.Background()
18+
database := store.GetMongoClient().Database(config.GetMongoConfig().DbName())
19+
collection := database.Collection(collectionName)
20+
21+
indexes := collection.Indexes()
22+
23+
for _, model := range models {
24+
_, err := indexes.CreateOne(context.Background(), model)
25+
if err != nil {
26+
errMessage := err.Error()
27+
if !(strings.Contains(errMessage, "IndexOptionsConflict") ||
28+
strings.Contains(errMessage, "IndexKeySpecsConflict")) {
29+
log.Log.Errorf(ctx, "failed to create indexes for collection: %s with error: %v", collectionName, err)
30+
return err
31+
}
32+
}
33+
}
34+
35+
log.Log.MongoInfof(ctx, "successfully created indexes for collection: %s", collectionName)
36+
return nil
37+
}

0 commit comments

Comments
 (0)