-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
(feat) added config | logger | repository | secrets
- Loading branch information
F.
committed
Dec 15, 2024
1 parent
bef7eda
commit 1a10bb6
Showing
39 changed files
with
5,189 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
BASE_DB_USERNAME=<username> | ||
BASE_DB_PASSWORD=<password> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
*out | ||
*logs | ||
*actions | ||
*notifications | ||
*tools | ||
plugins | ||
user_trunk.yaml | ||
user.yaml | ||
tmp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# Following source doesn't work in most setups | ||
ignored: | ||
- SC1090 | ||
- SC1091 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# Prettier friendly markdownlint config (all formatting rules disabled) | ||
extends: markdownlint/style/prettier |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
enable=all | ||
source-path=SCRIPTDIR | ||
disable=SC2154 | ||
|
||
# If you're having issues with shellcheck following source, disable the errors via: | ||
# disable=SC1090 | ||
# disable=SC1091 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
module.exports = { | ||
plugins: [ | ||
{ | ||
name: "preset-default", | ||
params: { | ||
overrides: { | ||
removeViewBox: false, // https://github.com/svg/svgo/issues/1128 | ||
sortAttrs: true, | ||
removeOffCanvasPaths: true, | ||
}, | ||
}, | ||
}, | ||
], | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# This file controls the behavior of Trunk: https://docs.trunk.io/cli | ||
# To learn more about the format of this file, see https://docs.trunk.io/reference/trunk-yaml | ||
version: 0.1 | ||
cli: | ||
version: 1.22.7 | ||
# Trunk provides extensibility via plugins. (https://docs.trunk.io/plugins) | ||
plugins: | ||
sources: | ||
- id: trunk | ||
ref: v1.6.6 | ||
uri: https://github.com/trunk-io/plugins | ||
# Many linters and tools depend on runtimes - configure them here. (https://docs.trunk.io/runtimes) | ||
runtimes: | ||
enabled: | ||
- go@1.21.0 | ||
- node@18.20.5 | ||
- python@3.10.8 | ||
# This is the section where you manage your linters. (https://docs.trunk.io/check/configuration) | ||
lint: | ||
enabled: | ||
- checkov@3.2.334 | ||
- git-diff-check | ||
- gofmt@1.20.4 | ||
- golangci-lint@1.62.2 | ||
- hadolint@2.12.1-beta | ||
- markdownlint@0.43.0 | ||
- prettier@3.4.2 | ||
- shellcheck@0.10.0 | ||
- shfmt@3.6.0 | ||
- svgo@3.3.2 | ||
- trufflehog@3.86.1 | ||
- yamllint@1.35.1 | ||
actions: | ||
disabled: | ||
- trunk-announce | ||
- trunk-check-pre-push | ||
- trunk-fmt-pre-commit | ||
enabled: | ||
- trunk-upgrade-available |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"log/slog" | ||
"os" | ||
|
||
"github.com/hyp3rd/base/internal/constants" | ||
"github.com/hyp3rd/base/internal/secrets" | ||
"github.com/hyp3rd/base/internal/secrets/providers/dotenv" | ||
) | ||
|
||
const ( | ||
sourceEnvFile = ".env" | ||
encryptedEnvFile = ".env.encrypted" | ||
) | ||
|
||
func main() { | ||
encryptionPassword, ok := os.LookupEnv("SECRETS_ENCRYPTION_PASSWORD") | ||
if !ok { | ||
fmt.Fprintf(os.Stderr, "SECRETS_ENCRYPTION_PASSWORD environment variable not set\n") | ||
os.Exit(1) | ||
} | ||
|
||
// Initialize the encrypted provider | ||
secretsProviderCfg := secrets.Config{ | ||
Source: secrets.EnvFile, | ||
Prefix: constants.EnvPrefix.String(), | ||
EnvPath: encryptedEnvFile, | ||
} | ||
|
||
provider, err := dotenv.NewEncrypted(secretsProviderCfg, encryptionPassword) | ||
if err != nil { | ||
fmt.Fprintf(os.Stderr, "Failed to initiate the configuration encryption provider: %v\n", err) | ||
os.Exit(1) | ||
} | ||
|
||
// Encrypt the existing .env file | ||
err = provider.EncryptFile(sourceEnvFile, encryptedEnvFile) | ||
if err != nil { | ||
fmt.Fprintf(os.Stderr, "Failed to encrypt the .env provided: %v\n", err) | ||
os.Exit(1) | ||
} | ||
|
||
slog.Info("Encryption complete") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,199 @@ | ||
package main | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"os" | ||
"os/signal" | ||
"syscall" | ||
"time" | ||
|
||
"github.com/hyp3rd/base/internal/config" | ||
"github.com/hyp3rd/base/internal/constants" | ||
"github.com/hyp3rd/base/internal/logger" | ||
"github.com/hyp3rd/base/internal/logger/adapter" | ||
"github.com/hyp3rd/base/internal/logger/output" | ||
"github.com/hyp3rd/base/internal/repository/pg" | ||
"github.com/hyp3rd/base/internal/secrets" | ||
"github.com/hyp3rd/base/internal/secrets/providers/dotenv" | ||
) | ||
|
||
const ( | ||
maxLogSize = 10 * 1024 * 1024 // 10 MB | ||
logsDir = "logs/pg/monitor" | ||
logsFile = "pg-monitor.log" | ||
|
||
configFileName = "config" | ||
|
||
monitorInterval = 10 * time.Second | ||
) | ||
|
||
func main() { | ||
ctx := context.Background() | ||
|
||
cfg := initConfig(ctx) | ||
log, multiWriter := initLogger(ctx, cfg.Environment) | ||
// Ensure proper cleanup with detailed error handling | ||
defer func() { | ||
if err := multiWriter.Sync(); err != nil { | ||
fmt.Fprintf(os.Stderr, "Logger sync failed: %+v\n", err) | ||
} | ||
|
||
if err := multiWriter.Close(); err != nil { | ||
fmt.Fprintf(os.Stderr, "Writer cleanup failed: %+v\n", err) | ||
} | ||
}() | ||
|
||
log.Info("Database monitor starting") | ||
|
||
dbManager := initDBmanager(ctx, cfg, log) | ||
|
||
// Create monitor with 1 second slow query threshold | ||
monitor := dbManager.NewMonitor(time.Second) | ||
|
||
// Start monitoring | ||
monitor.Start(ctx) | ||
defer monitor.Stop() | ||
|
||
// Create a ticker for periodic checks | ||
ticker := time.NewTicker(monitorInterval) | ||
defer ticker.Stop() | ||
|
||
// Setup signal handling | ||
sigChan := make(chan os.Signal, 1) | ||
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) | ||
|
||
// Main process loop | ||
for { | ||
select { | ||
case <-ticker.C: | ||
status := monitor.GetHealthStatus() | ||
if !status.Connected { | ||
log.Error("Database connection lost!") | ||
} else { | ||
log.Info("Database connection is healthy") | ||
} | ||
|
||
if status.PoolStats != nil { | ||
if status.PoolStats.SlowQueries > 0 { | ||
log.Warn("Detected slow queries") | ||
} | ||
} | ||
|
||
case sig := <-sigChan: | ||
log.Infof("Received signal: %v, shutting down...", sig) | ||
|
||
return | ||
case <-ctx.Done(): | ||
log.Info("Context cancelled, shutting down...") | ||
|
||
return | ||
} | ||
} | ||
} | ||
|
||
func initConfig(ctx context.Context) *config.Config { | ||
// Initialize the encrypted provider | ||
secretsProviderCfg := secrets.Config{ | ||
Source: secrets.EnvFile, | ||
Prefix: constants.EnvPrefix.String(), | ||
EnvPath: ".env.encrypted", | ||
} | ||
|
||
encryptionPassword, ok := os.LookupEnv("SECRETS_ENCRYPTION_PASSWORD") | ||
if !ok { | ||
fmt.Fprintf(os.Stderr, "SECRETS_ENCRYPTION_PASSWORD environment variable not set\n") | ||
os.Exit(1) | ||
} | ||
|
||
secretsProvider, err := dotenv.NewEncrypted(secretsProviderCfg, encryptionPassword) | ||
if err != nil { | ||
fmt.Fprintf(os.Stderr, "Secrets provider: %+v\n", err) | ||
os.Exit(1) | ||
} | ||
|
||
// Configure options for config initialization | ||
opts := config.Options{ | ||
ConfigName: configFileName, | ||
SecretsProvider: secretsProvider, | ||
Timeout: constants.DefaultTimeout, | ||
} | ||
|
||
cfg, err := config.NewConfig(ctx, opts) | ||
if err != nil { | ||
fmt.Fprintf(os.Stderr, "Failed to initialize config: %v\n", err) | ||
os.Exit(1) | ||
} | ||
|
||
return cfg | ||
} | ||
|
||
func initLogger(_ context.Context, environment string) (logger.Logger, *output.MultiWriter) { | ||
//nolint:mnd | ||
if err := os.MkdirAll(logsDir, 0o755); err != nil { | ||
fmt.Fprintf(os.Stderr, "Failed to create log directory: %v\n", err) | ||
os.Exit(1) | ||
} | ||
|
||
// Create file writer with proper error handling | ||
fileWriter, err := output.NewFileWriter(output.FileConfig{ | ||
Path: logsDir + "/" + logsFile, | ||
MaxSize: maxLogSize, | ||
Compress: true, | ||
}) | ||
if err != nil { | ||
fmt.Fprintf(os.Stderr, "Failed to create file writer: %v\n", err) | ||
os.Exit(1) | ||
} | ||
|
||
// Create console writer | ||
consoleWriter := output.NewConsoleWriter(os.Stdout, output.ColorModeAuto) | ||
|
||
// Create multi-writer with error handling | ||
multiWriter, err := output.NewMultiWriter(consoleWriter, fileWriter) | ||
if err != nil { | ||
fmt.Fprintf(os.Stderr, "Failed to create multi-writer: %v\n", err) | ||
fileWriter.Close() // Clean up the file writer | ||
os.Exit(1) | ||
} | ||
|
||
// Initialize the logger | ||
loggerCfg := logger.DefaultConfig() | ||
loggerCfg.Output = multiWriter | ||
loggerCfg.EnableJSON = true | ||
loggerCfg.TimeFormat = time.RFC3339 | ||
loggerCfg.EnableCaller = true | ||
loggerCfg.Level = logger.DebugLevel | ||
loggerCfg.AdditionalFields = []logger.Field{ | ||
{Key: "service", Value: "database-monitor"}, | ||
{Key: "environment", Value: environment}, | ||
} | ||
|
||
// Create the logger | ||
log, err := adapter.NewAdapter(loggerCfg) | ||
if err != nil { | ||
fmt.Fprintf(os.Stderr, "Failed to create logger: %+v\n", err) | ||
os.Exit(1) | ||
} | ||
|
||
return log, multiWriter | ||
} | ||
|
||
func initDBmanager(ctx context.Context, cfg *config.Config, log logger.Logger) *pg.Manager { | ||
// Initialize the database manager | ||
dbManager := pg.New(&cfg.DB, log) | ||
|
||
err := dbManager.Connect(ctx) | ||
if err != nil { | ||
log.Error("Failed to connect to database") | ||
panic(err) | ||
} | ||
|
||
if dbManager.IsConnected(ctx) { | ||
log.Info("Database connection successfully established") | ||
} else { | ||
log.Error("Database connection wasn't established") | ||
} | ||
|
||
return dbManager | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
--- | ||
# development | production | local | ||
environment: "development" | ||
servers: | ||
query_api: | ||
port: 8000 | ||
read_timeout: 15s | ||
write_timeout: 15s | ||
shutdown_timeout: 5s | ||
grpc: | ||
port: 50051 | ||
max_connection_idle: 15m | ||
max_connection_age: 30m | ||
max_connection_age_grace: 5m | ||
keepalive_time: 5m | ||
keepalive_timeout: 20s | ||
|
||
rate_limiter: | ||
requests_per_second: 100 | ||
burst_size: 50 | ||
|
||
db: | ||
host: <db_host> | ||
port: "5432" | ||
database: postgres | ||
# session | transaction | ||
pool_mode: "transaction" | ||
max_open_conns: 25 | ||
max_idle_conns: 25 | ||
conn_max_lifetime: 5m | ||
conn_attempts: 5 | ||
conn_timeout: 2s | ||
|
||
pubsub: | ||
project_id: "local-project" | ||
topic_id: "fingerprints" | ||
subscription_id: "base-sub" | ||
emulator_host: "localhost:8085" # For local development | ||
ack_deadline: 30s | ||
subscription: | ||
receive_max_outstanding_messages: 10 | ||
receive_num_goroutines: 4 | ||
receive_max_extension: 30s | ||
retry_policy: | ||
max_attempts: 5 | ||
minimum_backoff: 10s | ||
maximum_backoff: 600s |
Oops, something went wrong.