Skip to content

Commit 66b4422

Browse files
committed
refactor: use slog for logging
1 parent 59273d0 commit 66b4422

3 files changed

Lines changed: 89 additions & 54 deletions

File tree

‎go.mod‎

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,15 @@ require (
1515
github.com/cloudwego/base64x v0.1.5 // indirect
1616
github.com/cloudwego/iasm v0.2.0 // indirect
1717
github.com/dustin/go-humanize v1.0.1 // indirect
18+
github.com/fsnotify/fsnotify v1.9.0 // indirect
1819
github.com/gabriel-vasile/mimetype v1.4.9 // indirect
1920
github.com/gin-contrib/cors v1.7.6 // indirect
2021
github.com/gin-contrib/sse v1.1.0 // indirect
2122
github.com/glebarez/go-sqlite v1.21.2 // indirect
2223
github.com/go-playground/locales v0.14.1 // indirect
2324
github.com/go-playground/universal-translator v0.18.1 // indirect
2425
github.com/go-playground/validator/v10 v10.26.0 // indirect
26+
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
2527
github.com/goccy/go-json v0.10.5 // indirect
2628
github.com/google/uuid v1.6.0 // indirect
2729
github.com/hashicorp/errwrap v1.1.0 // indirect
@@ -38,14 +40,22 @@ require (
3840
github.com/ncruces/go-strftime v0.1.9 // indirect
3941
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
4042
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
43+
github.com/sagikazarmark/locafero v0.11.0 // indirect
44+
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
45+
github.com/spf13/afero v1.15.0 // indirect
46+
github.com/spf13/cast v1.10.0 // indirect
47+
github.com/spf13/pflag v1.0.10 // indirect
48+
github.com/spf13/viper v1.21.0 // indirect
49+
github.com/subosito/gotenv v1.6.0 // indirect
4150
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
4251
github.com/ugorji/go/codec v1.3.0 // indirect
52+
go.yaml.in/yaml/v3 v3.0.4 // indirect
4353
golang.org/x/arch v0.18.0 // indirect
4454
golang.org/x/crypto v0.39.0 // indirect
4555
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b // indirect
4656
golang.org/x/net v0.41.0 // indirect
4757
golang.org/x/sys v0.34.0 // indirect
48-
golang.org/x/text v0.26.0 // indirect
58+
golang.org/x/text v0.28.0 // indirect
4959
google.golang.org/protobuf v1.36.6 // indirect
5060
gopkg.in/yaml.v3 v3.0.1 // indirect
5161
modernc.org/libc v1.66.3 // indirect

‎go.sum‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
1717
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
1818
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
1919
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
20+
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
21+
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
2022
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
2123
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
2224
github.com/gabriel-vasile/mimetype v1.4.9 h1:5k+WDwEsD9eTLL8Tz3L0VnmVh9QxGjRmjBvAG7U/oYY=
@@ -43,6 +45,8 @@ github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBEx
4345
github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
4446
github.com/go-playground/validator/v10 v10.26.0 h1:SP05Nqhjcvz81uJaRfEV0YBSSSGMc/iMaVtFbr3Sw2k=
4547
github.com/go-playground/validator/v10 v10.26.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo=
48+
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
49+
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
4650
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
4751
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
4852
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
@@ -96,6 +100,18 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
96100
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
97101
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
98102
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
103+
github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc=
104+
github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik=
105+
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw=
106+
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U=
107+
github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
108+
github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg=
109+
github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
110+
github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
111+
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
112+
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
113+
github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU=
114+
github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY=
99115
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
100116
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
101117
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
@@ -109,12 +125,16 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl
109125
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
110126
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
111127
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
128+
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
129+
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
112130
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
113131
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
114132
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
115133
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
116134
github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA=
117135
github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4=
136+
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
137+
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
118138
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
119139
golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
120140
golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
@@ -142,6 +162,8 @@ golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
142162
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
143163
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
144164
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
165+
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
166+
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
145167
golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo=
146168
golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=
147169
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=

‎main.go‎

Lines changed: 56 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@ package main
22

33
import (
44
"context"
5+
"fmt"
56
"log"
6-
"os"
7-
"strconv"
8-
"strings"
7+
"log/slog"
98
"time"
109
"tinyauth-analytics/internal/controller"
1110
"tinyauth-analytics/internal/middleware"
@@ -14,85 +13,89 @@ import (
1413

1514
"github.com/gin-contrib/cors"
1615
"github.com/gin-gonic/gin"
16+
"github.com/spf13/viper"
1717
"gorm.io/gorm"
1818
)
1919

2020
var version = "development"
2121

22-
func main() {
23-
log.SetFlags(log.LstdFlags | log.Lshortfile)
24-
25-
dbPath := os.Getenv("DB_PATH")
26-
27-
if dbPath == "" {
28-
dbPath = "/data/analytics.db"
29-
}
30-
31-
port := os.Getenv("PORT")
32-
33-
if port == "" {
34-
port = "8080"
35-
}
36-
37-
address := os.Getenv("ADDRESS")
22+
type config struct {
23+
DatabasePath string `mapstructure:"db_path"`
24+
Port string `mapstructure:"port"`
25+
Address string `mapstructure:"address"`
26+
RateLimitCount int `mapstructure:"rate_limit_count"`
27+
CORSAllowedOrigins []string `mapstructure:"cors_allowed_origins"`
28+
TrustedProxies []string `mapstructure:"trusted_proxies"`
29+
LogLevel string `mapstructure:"log_level"`
30+
}
3831

39-
if address == "" {
40-
address = "0.0.0.0"
41-
}
32+
func main() {
33+
logger := slog.New(slog.NewTextHandler(log.Writer(), &slog.HandlerOptions{
34+
Level: slog.LevelInfo,
35+
}))
36+
slog.SetDefault(logger)
4237

43-
var rateLimitCount int
38+
v := viper.New()
4439

45-
rateLimitCountStr := os.Getenv("RATE_LIMIT_COUNT")
40+
v.AutomaticEnv()
4641

47-
if rateLimitCountStr == "" {
48-
rateLimitCount = 3
49-
} else {
50-
var err error
42+
v.SetDefault("db_path", "/data/analytics.db")
43+
v.SetDefault("port", "8080")
44+
v.SetDefault("address", "0.0.0.0")
45+
v.SetDefault("rate_limit_count", 3)
46+
v.SetDefault("cors_allowed_origins", "*")
47+
v.SetDefault("trusted_proxies", "")
48+
v.SetDefault("log_level", "info")
5149

52-
rateLimitCount, err = strconv.Atoi(rateLimitCountStr)
50+
var conf config
5351

54-
if err != nil {
55-
log.Fatal("invalid RATE_LIMIT_COUNT:", err)
56-
}
52+
if err := v.Unmarshal(&conf); err != nil {
53+
slog.Error("failed to parse config", "error", err)
5754
}
5855

59-
var corsAllowedOrigins []string
60-
61-
corsAllowedOriginsStr := os.Getenv("CORS_ALLOWED_ORIGINS")
62-
63-
if corsAllowedOriginsStr != "" {
64-
corsAllowedOrigins = append(corsAllowedOrigins, strings.Split(corsAllowedOriginsStr, ",")...)
65-
} else {
66-
corsAllowedOrigins = append(corsAllowedOrigins, "*")
56+
switch conf.LogLevel {
57+
case "debug":
58+
slog.SetLogLoggerLevel(slog.LevelDebug)
59+
case "info":
60+
slog.SetLogLoggerLevel(slog.LevelInfo)
61+
case "warn":
62+
slog.SetLogLoggerLevel(slog.LevelWarn)
63+
case "error":
64+
slog.SetLogLoggerLevel(slog.LevelError)
65+
default:
66+
slog.Error("invalid log level", "level", conf.LogLevel)
6767
}
6868

69-
trustedProxies := os.Getenv("TRUSTED_PROXIES")
70-
7169
dbSvc := service.NewDatabaseService(service.DatabaseServiceConfig{
72-
DatabasePath: dbPath,
70+
DatabasePath: conf.DatabasePath,
7371
})
7472

7573
if err := dbSvc.Init(); err != nil {
76-
log.Fatal("failed to initialize database:", err)
74+
slog.Error("failed to initialize database", "error", err)
7775
}
7876

7977
db := dbSvc.GetDatabase()
8078

8179
cacheSvc := service.NewCacheService()
8280

8381
engine := gin.Default()
82+
engine.Use(gin.Recovery())
83+
84+
if conf.LogLevel == "debug" || conf.LogLevel == "info" {
85+
engine.Use(gin.Logger())
86+
}
8487

8588
engine.Use(cors.New(
8689
cors.Config{
87-
AllowOrigins: corsAllowedOrigins,
90+
AllowOrigins: conf.CORSAllowedOrigins,
8891
},
8992
))
9093

91-
engine.SetTrustedProxies(strings.Split(trustedProxies, ","))
94+
engine.SetTrustedProxies(conf.TrustedProxies)
9295

9396
api := engine.Group("/v1")
9497

95-
rateLimitMiddleware := middleware.NewRateLimitMiddleware(db, cacheSvc, rateLimitCount)
98+
rateLimitMiddleware := middleware.NewRateLimitMiddleware(db, cacheSvc, conf.RateLimitCount)
9699

97100
instancesCtrl := controller.NewInstancesController(api, db, rateLimitMiddleware)
98101

@@ -104,10 +107,10 @@ func main() {
104107

105108
go clearOldSessions(db)
106109

107-
log.Printf("Starting analytics server on %s:%s (version: %s)", address, port, version)
110+
slog.Info("starting analytics server", "address", conf.Address, "port", conf.Port, "version", version)
108111

109-
if err := engine.Run(address + ":" + port); err != nil {
110-
log.Fatal("failed to start server:", err)
112+
if err := engine.Run(conf.Address + ":" + conf.Port); err != nil {
113+
slog.Error("failed to start server", "error", err)
111114
}
112115
}
113116

@@ -116,17 +119,17 @@ func clearOldSessions(db *gorm.DB) {
116119
defer ticker.Stop()
117120

118121
for ; true; <-ticker.C {
119-
log.Println("Clearing old sessions")
122+
slog.Info("clearing old sessions")
120123

121124
ctx := context.Background()
122125
cutoffTime := time.Now().Add(time.Duration(-48) * time.Hour).UnixMilli()
123126
rowsAffected, err := gorm.G[model.Instance](db).Where("last_seen < ?", cutoffTime).Delete(ctx)
124127

125128
if err != nil {
126-
log.Println("Failed to clear old sessions:", err)
129+
slog.Warn("failed to clear old sessions: ", "error", err)
127130
continue
128131
}
129132

130-
log.Printf("Cleared %d old sessions\n", rowsAffected)
133+
slog.Info(fmt.Sprintf("cleared %d old sessions", rowsAffected))
131134
}
132135
}

0 commit comments

Comments
 (0)