@@ -2,41 +2,33 @@ package main
22
33import (
44 "context"
5- "flag"
65 "fmt"
6+ "io/fs"
77 "log/slog"
8+ "strings"
89 "time"
910
1011 "github.com/jackc/pgx/v5/pgtype"
1112 "github.com/jackc/pgx/v5/pgxpool"
1213 "github.com/robbert229/jaeger-postgresql/internal/logger"
1314 "github.com/robbert229/jaeger-postgresql/internal/sql"
15+ "github.com/spf13/pflag"
16+ "github.com/spf13/viper"
1417 "go.uber.org/fx"
1518 "go.uber.org/fx/fxevent"
1619)
1720
18- var (
19- databaseURLFlag = flag .String ("database.url" , "" , "the postgres connection url to use to connect to the database" )
20- databaseMaxConnsFlag = flag .Int ("database.max-conns" , 20 , "Max number of database connections of which the plugin will try to maintain at any given time" )
21- loglevelFlag = flag .String ("log-level" , "warn" , "Minimal allowed log level" )
22- maxSpanAgeFlag = flag .Duration ("max-span-age" , time .Hour * 24 , "Maximum age of a span before it will be cleaned" )
23- )
24-
2521// ProvideLogger returns a function that provides a logger
2622func ProvideLogger () any {
27- return func () (* slog.Logger , error ) {
28- return logger .New (loglevelFlag )
23+ return func (cfg Config ) (* slog.Logger , error ) {
24+ return logger .New (& cfg . LogLevel )
2925 }
3026}
3127
3228// ProvidePgxPool returns a function that provides a pgx pool
3329func ProvidePgxPool () any {
34- return func (logger * slog.Logger , lc fx.Lifecycle ) (* pgxpool.Pool , error ) {
35- if databaseURLFlag == nil {
36- return nil , fmt .Errorf ("invalid database url" )
37- }
38-
39- databaseURL := * databaseURLFlag
30+ return func (cfg Config , logger * slog.Logger , lc fx.Lifecycle ) (* pgxpool.Pool , error ) {
31+ databaseURL := cfg .Database .URL
4032 if databaseURL == "" {
4133 return nil , fmt .Errorf ("invalid database url" )
4234 }
@@ -54,10 +46,10 @@ func ProvidePgxPool() any {
5446 // handle max conns
5547 {
5648 var maxConns int32
57- if databaseMaxConnsFlag == nil {
49+ if cfg . Database . MaxConns == 0 {
5850 maxConns = 20
5951 } else {
60- maxConns = int32 (* databaseMaxConnsFlag )
52+ maxConns = int32 (cfg . Database . MaxConns )
6153 }
6254
6355 pgxconfig .MaxConns = maxConns
@@ -89,33 +81,79 @@ func ProvidePgxPool() any {
8981}
9082
9183// clean purges the old roles from the database
92- func clean (ctx context.Context , pool * pgxpool.Pool ) (int64 , error ) {
84+ func clean (ctx context.Context , pool * pgxpool.Pool , maxAge time. Duration ) (int64 , error ) {
9385 q := sql .New (pool )
94- result , err := q .CleanSpans (ctx , pgtype.Timestamp {Time : time .Now ().Add (- 1 * * maxSpanAgeFlag ), Valid : true })
86+ result , err := q .CleanSpans (ctx , pgtype.Timestamp {Time : time .Now ().Add (- 1 * maxAge ), Valid : true })
9587 if err != nil {
9688 return 0 , err
9789 }
9890
9991 return result , nil
10092}
10193
102- func main () {
103- flag .Parse ()
94+ type Config struct {
95+ Database struct {
96+ URL string `mapstructure:"url"`
97+ MaxConns int `mapstructure:"max-conns"`
98+ } `mapstructure:"database"`
99+
100+ LogLevel string `mapstructure:"log-level"`
104101
102+ MaxSpanAge time.Duration `mapstructure:"max-span-age"`
103+ }
104+
105+ func ProvideConfig () func () (Config , error ) {
106+ return func () (Config , error ) {
107+ pflag .String ("database.url" , "" , "the postgres connection url to use to connect to the database" )
108+ pflag .Int ("database.max-conns" , 20 , "Max number of database connections of which the plugin will try to maintain at any given time" )
109+ pflag .String ("log-level" , "warn" , "Minimal allowed log level" )
110+ pflag .Duration ("max-span-age" , time .Hour * 24 , "Maximum age of a span before it will be cleaned" )
111+
112+ v := viper .New ()
113+ v .SetEnvPrefix ("JAEGER_POSTGRESQL" )
114+ v .AutomaticEnv ()
115+ v .SetConfigFile ("jaeger-postgresql" )
116+ v .SetConfigType ("yaml" )
117+ v .AddConfigPath ("." )
118+ v .SetEnvKeyReplacer (strings .NewReplacer ("." , "_" , "-" , "_" ))
119+ pflag .Parse ()
120+ v .BindPFlags (pflag .CommandLine )
121+
122+ var cfg Config
123+ if err := v .ReadInConfig (); err != nil {
124+ _ , ok := err .(* fs.PathError )
125+ _ , ok2 := err .(viper.ConfigFileNotFoundError )
126+
127+ if ! ok && ! ok2 {
128+ return cfg , fmt .Errorf ("failed to read in config: %w" , err )
129+ }
130+ }
131+
132+ err := v .Unmarshal (& cfg )
133+ if err != nil {
134+ return cfg , fmt .Errorf ("failed to decode configuration: %w" , err )
135+ }
136+
137+ return cfg , nil
138+ }
139+ }
140+
141+ func main () {
105142 fx .New (
106143 fx .WithLogger (func (logger * slog.Logger ) fxevent.Logger {
107144 return & fxevent.SlogLogger {Logger : logger .With ("component" , "uber/fx" )}
108145 }),
109146 fx .Provide (
147+ ProvideConfig (),
110148 ProvideLogger (),
111149 ProvidePgxPool (),
112150 ),
113- fx .Invoke (func (pool * pgxpool.Pool , lc fx.Lifecycle , logger * slog.Logger , stopper fx.Shutdowner ) error {
151+ fx .Invoke (func (cfg Config , pool * pgxpool.Pool , lc fx.Lifecycle , logger * slog.Logger , stopper fx.Shutdowner ) error {
114152 go func (ctx context.Context ) {
115153 ctx , cancelFn := context .WithTimeout (ctx , time .Minute )
116154 defer cancelFn ()
117155
118- count , err := clean (ctx , pool )
156+ count , err := clean (ctx , pool , cfg . MaxSpanAge )
119157 if err != nil {
120158 logger .Error ("failed to clean database" , "err" , err )
121159 stopper .Shutdown (fx .ExitCode (1 ))
0 commit comments