feat(observability): configurable logging, request ids and error logs
- internal/logging: LOG_LEVEL/LOG_FORMAT parsing and slog handler - request_id middleware (X-Request-ID or generated, echoed) + debug access log - httpx registers errors; middleware logs internal causes with request_id - health excluded, objects/sse debug-only, no query/body/secrets in logs - new observability capability spec; README/.env.example docs
This commit is contained in:
@@ -5,6 +5,8 @@ import (
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"galo/internal/logging"
|
||||
)
|
||||
|
||||
type Postgres struct {
|
||||
@@ -63,6 +65,11 @@ type Database struct {
|
||||
SQLitePath string
|
||||
}
|
||||
|
||||
type Log struct {
|
||||
Level string
|
||||
Format string
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Postgres Postgres
|
||||
S3 S3
|
||||
@@ -72,6 +79,7 @@ type Config struct {
|
||||
Server Server
|
||||
SSE SSE
|
||||
Worker Worker
|
||||
Log Log
|
||||
}
|
||||
|
||||
func Load() (*Config, error) {
|
||||
@@ -125,6 +133,15 @@ func Load() (*Config, error) {
|
||||
return nil, fmt.Errorf("invalid WORKER_PENDING_TTL: %w", err)
|
||||
}
|
||||
|
||||
logLevel := getEnv("LOG_LEVEL", "info")
|
||||
if _, err := logging.ParseLevel(logLevel); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
logFormat := getEnv("LOG_FORMAT", "json")
|
||||
if _, err := logging.ParseFormat(logFormat); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cfg := &Config{
|
||||
Postgres: Postgres{
|
||||
Host: getEnv("PG_HOST", "pg.localnet"),
|
||||
@@ -169,6 +186,10 @@ func Load() (*Config, error) {
|
||||
Batch: workerBatch,
|
||||
PendingTTL: workerPendingTTL,
|
||||
},
|
||||
Log: Log{
|
||||
Level: logLevel,
|
||||
Format: logFormat,
|
||||
},
|
||||
}
|
||||
|
||||
switch cfg.Database.Backend {
|
||||
|
||||
Reference in New Issue
Block a user