Skip to content

Commit f0cbd8c

Browse files
adds Zap logger so it can be seen in Loki
1 parent 9541e02 commit f0cbd8c

File tree

8 files changed

+78
-32
lines changed

8 files changed

+78
-32
lines changed

README.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,16 @@
1515

1616

1717
## Local Development
18-
This project uses [Task](https://taskfile.dev/) to common development workflows, Run `task` to see all available tasks.
18+
Project uses [Task](https://taskfile.dev/) to common dev workflows, Run `task` to see all available tasks.
1919

2020
```bash
2121
task local:setup
2222
task local:start
2323

2424
Tilt UI: http://localhost:10350
25-
2625
Jaeger UI: http://localhost:16686
27-
PostgreSQL: localhost:5432
28-
- Connection: psql postgresql://{.env.POSTGRES_USER}:{.env.POSTGRES_PASSWORD}@localhost:5432/
26+
Postgre: localhost:5432
27+
Postgre connection psql postgresql://{.env.POSTGRES_USER}:{.env.POSTGRES_PASSWORD}@localhost:5432/
2928
```
3029

3130
## Production Links

apps/semcache-service/api/openapi.yaml

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,11 @@
11
openapi: 3.0.3
22
info:
33
title: Semcache Service API
4-
description: |
5-
Semantic cache service for storing and searching key-value pairs with metadata and TTL support.
64

7-
## Features
8-
- Store key-value pairs with optional metadata
9-
- TTL (Time To Live) support for automatic expiration
10-
- Flexible search by key or metadata
11-
- Unique key constraint
12-
- Automatic expiration filtering
13-
version: 1.0.0
5+
version: 0.1.0
146
contact:
157
name: API Support
16-
url: https://github.com/nextinterfaces/semcache-service
8+
url: https://github.com/nextinterfaces/roussev.com
179

1810
servers:
1911
- url: https://app.roussev.com/semcache

apps/semcache-service/cmd/server/main.go

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"github.com/nextinterfaces/semcache-service/internal/config"
1616
"github.com/nextinterfaces/semcache-service/internal/database"
1717
"github.com/nextinterfaces/semcache-service/internal/handlers"
18+
"github.com/nextinterfaces/semcache-service/internal/logger"
1819
"github.com/nextinterfaces/semcache-service/internal/models"
1920
"github.com/nextinterfaces/semcache-service/internal/util"
2021
"go.opentelemetry.io/otel"
@@ -33,19 +34,27 @@ func main() {
3334
func run() error {
3435
cfg, err := config.Load()
3536
cfgJSON, _ := json.MarshalIndent(util.RedactedConfig(cfg), "", " ")
36-
log.Println("Loaded configuration:\n" + string(cfgJSON))
3737
if err != nil {
3838
return fmt.Errorf("failed to load config: %w", err)
3939
}
4040

41+
// Initialize logger
42+
logger.InitLogger(cfg.Debug)
43+
defer logger.Sync()
44+
45+
logger.Logger.Info("Starting semcache-service")
46+
logger.Logger.Debug("Debug mode enabled")
47+
logger.Logger.Info("Loaded configuration:\n" + string(cfgJSON))
48+
//logger.Logger.Info("Server port", zap.Int("port", cfg.Server.Port))
49+
4150
// Initialize OpenTelemetry
4251
if cfg.OTEL.Enabled {
4352
shutdown, err := initTracer(cfg)
4453
if err != nil {
45-
log.Printf("Warning: Failed to initialize tracer: %v", err)
54+
logger.Logger.Warn(fmt.Sprintf("Failed to initialize tracer: %v", err))
4655
} else {
4756
defer shutdown()
48-
log.Printf("OpenTelemetry tracing enabled: %s", cfg.OTEL.Endpoint)
57+
logger.Logger.Info(fmt.Sprintf("OpenTelemetry tracing enabled: %s", cfg.OTEL.Endpoint))
4958
}
5059
}
5160

@@ -92,22 +101,22 @@ func run() error {
92101
go func() {
93102
addr := fmt.Sprintf(":%d", port)
94103
if err := e.Start(addr); err != nil {
95-
log.Printf("Server error: %v", err)
104+
logger.Logger.Error(fmt.Sprintf("Server error: %v", err))
96105
}
97106
}()
98107

99-
log.Printf("Server started, endpoints:")
100-
log.Printf(" http://localhost:%d/v1/health", port)
101-
log.Printf(" http://localhost:%d/docs", port)
102-
log.Printf(" POST http://localhost:%d/v1/create", port)
103-
log.Printf(" POST http://localhost:%d/v1/search", port)
108+
logger.Logger.Info(fmt.Sprintf("Server started, endpoints:"))
109+
logger.Logger.Info(fmt.Sprintf(" http://localhost:%d/v1/health", port))
110+
logger.Logger.Info(fmt.Sprintf(" http://localhost:%d/docs", port))
111+
logger.Logger.Info(fmt.Sprintf(" POST http://localhost:%d/v1/create", port))
112+
logger.Logger.Info(fmt.Sprintf(" POST http://localhost:%d/v1/search", port))
104113

105114
// Wait for interrupt signal to gracefully shutdown the server
106115
quit := make(chan os.Signal, 1)
107116
signal.Notify(quit, os.Interrupt, syscall.SIGTERM)
108117
<-quit
109118

110-
log.Println("Shutting down server...")
119+
logger.Logger.Info(fmt.Sprintf("Shutting down server..."))
111120

112121
// Graceful shutdown with timeout
113122
ctx, cancel = context.WithTimeout(context.Background(), 10*time.Second)
@@ -117,7 +126,7 @@ func run() error {
117126
return fmt.Errorf("server shutdown error: %w", err)
118127
}
119128

120-
log.Println("Server stopped")
129+
logger.Logger.Info(fmt.Sprintf("Server stopped"))
121130
return nil
122131
}
123132

@@ -156,7 +165,7 @@ func initTracer(cfg *config.Config) (func(), error) {
156165
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
157166
defer cancel()
158167
if err := tp.Shutdown(ctx); err != nil {
159-
log.Printf("Error shutting down tracer provider: %v", err)
168+
logger.Logger.Info(fmt.Sprintf("Error shutting down tracer provider: %v", err))
160169
}
161170
}, nil
162171
}

apps/semcache-service/go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ require (
88
go.opentelemetry.io/otel v1.24.0
99
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.24.0
1010
go.opentelemetry.io/otel/sdk v1.24.0
11+
go.uber.org/zap v1.27.0
1112
)
1213

1314
require (
@@ -25,6 +26,7 @@ require (
2526
go.opentelemetry.io/otel/metric v1.24.0 // indirect
2627
go.opentelemetry.io/otel/trace v1.24.0 // indirect
2728
go.opentelemetry.io/proto/otlp v1.1.0 // indirect
29+
go.uber.org/multierr v1.10.0 // indirect
2830
golang.org/x/crypto v0.22.0 // indirect
2931
golang.org/x/net v0.24.0 // indirect
3032
golang.org/x/sys v0.19.0 // indirect

apps/semcache-service/go.sum

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,12 @@ go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y
4646
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
4747
go.opentelemetry.io/proto/otlp v1.1.0 h1:2Di21piLrCqJ3U3eXGCTPHE9R8Nh+0uglSnOyxikMeI=
4848
go.opentelemetry.io/proto/otlp v1.1.0/go.mod h1:GpBHCBWiqvVLDqmHZsoMM3C5ySeKTC7ej/RNTae6MdY=
49+
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
50+
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
51+
go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
52+
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
53+
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
54+
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
4955
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
5056
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
5157
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=

apps/semcache-service/internal/config/config.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ type Config struct {
1111
Server ServerConfig
1212
Database DatabaseConfig
1313
OTEL OTELConfig
14+
Debug bool
1415
}
1516

1617
// ServerConfig holds server configuration
@@ -71,6 +72,7 @@ func Load() (*Config, error) {
7172
Endpoint: getEnv("OTEL_EXPORTER_OTLP_ENDPOINT", "http://localhost:4318"),
7273
ServiceName: getEnv("OTEL_SERVICE_NAME", "semcache-service"),
7374
},
75+
Debug: true,
7476
}, nil
7577
}
7678

@@ -115,4 +117,3 @@ func (c *DatabaseConfig) ConnectionString() string {
115117
c.Host, c.Port, c.User, c.Password, c.Database, c.SSLMode,
116118
)
117119
}
118-

apps/semcache-service/internal/database/database.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ import (
44
"context"
55
"database/sql"
66
"fmt"
7-
"log"
87
"time"
98

109
_ "github.com/lib/pq"
1110
"github.com/nextinterfaces/semcache-service/internal/config"
11+
"github.com/nextinterfaces/semcache-service/internal/logger"
1212
)
1313

1414
// DB wraps the database connection
@@ -19,7 +19,7 @@ type DB struct {
1919
// New creates a new database connection
2020
func New(cfg *config.DatabaseConfig) (*DB, error) {
2121
connStr := cfg.ConnectionString()
22-
22+
2323
db, err := sql.Open("postgres", connStr)
2424
if err != nil {
2525
return nil, fmt.Errorf("failed to open database: %w", err)
@@ -38,7 +38,7 @@ func New(cfg *config.DatabaseConfig) (*DB, error) {
3838
return nil, fmt.Errorf("failed to ping database: %w", err)
3939
}
4040

41-
log.Printf("Connected to database: %s:%d/%s", cfg.Host, cfg.Port, cfg.Database)
41+
logger.Logger.Info(fmt.Sprintf("Connected to database: %s:%d/%s", cfg.Host, cfg.Port, cfg.Database))
4242

4343
return &DB{db}, nil
4444
}
@@ -66,7 +66,7 @@ func (db *DB) InitSchema(ctx context.Context) error {
6666
return fmt.Errorf("failed to create schema: %w", err)
6767
}
6868

69-
log.Println("Database schema initialized")
69+
logger.Logger.Info(fmt.Sprintf("Database schema initialized"))
7070
return nil
7171
}
7272

@@ -79,4 +79,3 @@ func (db *DB) HealthCheck(ctx context.Context) error {
7979
func (db *DB) Close() error {
8080
return db.DB.Close()
8181
}
82-
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package logger
2+
3+
import (
4+
"go.uber.org/zap"
5+
"go.uber.org/zap/zapcore"
6+
)
7+
8+
var (
9+
// Logger is the global logger instance
10+
Logger *zap.Logger
11+
)
12+
13+
// InitLogger initializes the global logger
14+
func InitLogger(debug bool) {
15+
var config zap.Config
16+
if debug {
17+
config = zap.NewDevelopmentConfig()
18+
config.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder
19+
} else {
20+
config = zap.NewProductionConfig()
21+
config.EncoderConfig.MessageKey = "message"
22+
config.EncoderConfig.LevelKey = "level"
23+
config.EncoderConfig.EncodeLevel = zapcore.LowercaseLevelEncoder
24+
config.EncoderConfig.TimeKey = "time"
25+
config.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
26+
}
27+
28+
var err error
29+
Logger, err = config.Build()
30+
if err != nil {
31+
panic("failed to initialize logger: " + err.Error())
32+
}
33+
}
34+
35+
// Sync flushes any buffered log entries
36+
func Sync() {
37+
_ = Logger.Sync()
38+
}

0 commit comments

Comments
 (0)