Skip to content

Commit

Permalink
feat: added extra configuration methods (#40)
Browse files Browse the repository at this point in the history
  • Loading branch information
robbert229 authored Apr 4, 2024
1 parent c90e2d2 commit 947140b
Show file tree
Hide file tree
Showing 6 changed files with 185 additions and 75 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Installation is done through the use of a helm chart.
<!-- x-release-please-start-version -->
```
helm install myrelease oci://ghcr.io/robbert229/jaeger-postgresql/charts/jaeger-postgresql \
--version v1.6.0 \
--version v1.7.0 \
--set database.url='postgresql://postgres:password@database:5432/jaeger'
```
<!-- x-release-please-end -->
Expand Down
33 changes: 22 additions & 11 deletions charts/jaeger-postgresql/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,28 @@ spec:
{{- toYaml .Values.service.podSecurityContext | nindent 8 }}
containers:
- name: jaeger-postgresql
args:
- "--log-level"
- "{{ .Values.service.logLevel}}"
- "--database.url"
- "{{ .Values.database.url }}"
- "--database.max-conns"
- "{{ .Values.database.maxConns}}"
- "--grpc-server.host-port"
- "0.0.0.0:12345"
- "--admin.http.host-port"
- "0.0.0.0:12346"
env:
{{- range $key, $value := .Values.extraEnvs }}
- name: {{ $key }}
value: {{ $value | quote }}
{{- end }}
- name: JAEGER_POSTGRESQL_LOG_LEVEL
value: {{ .Values.service.logLevel | quote }}
- name: JAEGER_POSTGRESQL_DATABASE_MAX_CONNS
value: {{ .Values.database.maxConns | quote }}
- name: JAEGER_POSTGRESQL_DATABASE_URL
{{ with .Values.database.urlFromSecret }}
valueFrom:
secretKeyRef:
name: {{ .name }}
key: {{ .key }}
{{ else }}
value: {{ .Values.database.url | quote }}
{{ end }}
- name: JAEGER_POSTGRESQL_GRPC_SERVER_HOST_PORT
value: "0.0.0.0:12345"
- name: JAEGER_POSTGRESQL_ADMIN_HTTP_HOST_PORT
value: "0.0.0.0:12346"
securityContext:
{{- toYaml .Values.service.securityContext | nindent 12 }}
image: "{{ .Values.service.image }}"
Expand Down
11 changes: 10 additions & 1 deletion charts/jaeger-postgresql/values-template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@ database:
url: "postgresql://postgres:password@localhost:5432/jaeger"
maxConns: 10

# -- (object) Source database url from a secret
urlFromSecret:
# name of secret
# name: ""
# key within secret containing url
# key: ""

service:
logLevel: "info"

Expand Down Expand Up @@ -107,4 +114,6 @@ cleaner:

tolerations: []

affinity: {}
affinity: {}

extraEnvs: []
86 changes: 62 additions & 24 deletions cmd/jaeger-postgresql-cleaner/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,33 @@ package main

import (
"context"
"flag"
"fmt"
"io/fs"
"log/slog"
"strings"
"time"

"github.com/jackc/pgx/v5/pgtype"
"github.com/jackc/pgx/v5/pgxpool"
"github.com/robbert229/jaeger-postgresql/internal/logger"
"github.com/robbert229/jaeger-postgresql/internal/sql"
"github.com/spf13/pflag"
"github.com/spf13/viper"
"go.uber.org/fx"
"go.uber.org/fx/fxevent"
)

var (
databaseURLFlag = flag.String("database.url", "", "the postgres connection url to use to connect to the database")
databaseMaxConnsFlag = flag.Int("database.max-conns", 20, "Max number of database connections of which the plugin will try to maintain at any given time")
loglevelFlag = flag.String("log-level", "warn", "Minimal allowed log level")
maxSpanAgeFlag = flag.Duration("max-span-age", time.Hour*24, "Maximum age of a span before it will be cleaned")
)

// ProvideLogger returns a function that provides a logger
func ProvideLogger() any {
return func() (*slog.Logger, error) {
return logger.New(loglevelFlag)
return func(cfg Config) (*slog.Logger, error) {
return logger.New(&cfg.LogLevel)
}
}

// ProvidePgxPool returns a function that provides a pgx pool
func ProvidePgxPool() any {
return func(logger *slog.Logger, lc fx.Lifecycle) (*pgxpool.Pool, error) {
if databaseURLFlag == nil {
return nil, fmt.Errorf("invalid database url")
}

databaseURL := *databaseURLFlag
return func(cfg Config, logger *slog.Logger, lc fx.Lifecycle) (*pgxpool.Pool, error) {
databaseURL := cfg.Database.URL
if databaseURL == "" {
return nil, fmt.Errorf("invalid database url")
}
Expand All @@ -54,10 +46,10 @@ func ProvidePgxPool() any {
// handle max conns
{
var maxConns int32
if databaseMaxConnsFlag == nil {
if cfg.Database.MaxConns == 0 {
maxConns = 20
} else {
maxConns = int32(*databaseMaxConnsFlag)
maxConns = int32(cfg.Database.MaxConns)
}

pgxconfig.MaxConns = maxConns
Expand Down Expand Up @@ -89,33 +81,79 @@ func ProvidePgxPool() any {
}

// clean purges the old roles from the database
func clean(ctx context.Context, pool *pgxpool.Pool) (int64, error) {
func clean(ctx context.Context, pool *pgxpool.Pool, maxAge time.Duration) (int64, error) {
q := sql.New(pool)
result, err := q.CleanSpans(ctx, pgtype.Timestamp{Time: time.Now().Add(-1 * *maxSpanAgeFlag), Valid: true})
result, err := q.CleanSpans(ctx, pgtype.Timestamp{Time: time.Now().Add(-1 * maxAge), Valid: true})
if err != nil {
return 0, err
}

return result, nil
}

func main() {
flag.Parse()
type Config struct {
Database struct {
URL string `mapstructure:"url"`
MaxConns int `mapstructure:"max-conns"`
} `mapstructure:"database"`

LogLevel string `mapstructure:"log-level"`

MaxSpanAge time.Duration `mapstructure:"max-span-age"`
}

func ProvideConfig() func() (Config, error) {
return func() (Config, error) {
pflag.String("database.url", "", "the postgres connection url to use to connect to the database")
pflag.Int("database.max-conns", 20, "Max number of database connections of which the plugin will try to maintain at any given time")
pflag.String("log-level", "warn", "Minimal allowed log level")
pflag.Duration("max-span-age", time.Hour*24, "Maximum age of a span before it will be cleaned")

v := viper.New()
v.SetEnvPrefix("JAEGER_POSTGRESQL")
v.AutomaticEnv()
v.SetConfigFile("jaeger-postgresql")
v.SetConfigType("yaml")
v.AddConfigPath(".")
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_", "-", "_"))
pflag.Parse()
v.BindPFlags(pflag.CommandLine)

var cfg Config
if err := v.ReadInConfig(); err != nil {
_, ok := err.(*fs.PathError)
_, ok2 := err.(viper.ConfigFileNotFoundError)

if !ok && !ok2 {
return cfg, fmt.Errorf("failed to read in config: %w", err)
}
}

err := v.Unmarshal(&cfg)
if err != nil {
return cfg, fmt.Errorf("failed to decode configuration: %w", err)
}

return cfg, nil
}
}

func main() {
fx.New(
fx.WithLogger(func(logger *slog.Logger) fxevent.Logger {
return &fxevent.SlogLogger{Logger: logger.With("component", "uber/fx")}
}),
fx.Provide(
ProvideConfig(),
ProvideLogger(),
ProvidePgxPool(),
),
fx.Invoke(func(pool *pgxpool.Pool, lc fx.Lifecycle, logger *slog.Logger, stopper fx.Shutdowner) error {
fx.Invoke(func(cfg Config, pool *pgxpool.Pool, lc fx.Lifecycle, logger *slog.Logger, stopper fx.Shutdowner) error {
go func(ctx context.Context) {
ctx, cancelFn := context.WithTimeout(ctx, time.Minute)
defer cancelFn()

count, err := clean(ctx, pool)
count, err := clean(ctx, pool, cfg.MaxSpanAge)
if err != nil {
logger.Error("failed to clean database", "err", err)
stopper.Shutdown(fx.ExitCode(1))
Expand Down
Loading

0 comments on commit 947140b

Please sign in to comment.