From c98f5fde211d13591be474edd8af6b244ac6bf75 Mon Sep 17 00:00:00 2001 From: James Ranson Date: Thu, 15 Aug 2024 18:49:10 -0600 Subject: [PATCH] Refactor logging (#733) * remove go-kit/log dependency * remove go-stack dependency * use 'any' instead of 'interface{}' * add noop logger to tests that need it --- go.mod | 3 - go.sum | 6 - pkg/backends/alb/response_merge_test.go | 5 +- pkg/backends/backend_test.go | 4 +- pkg/backends/backends.go | 3 +- pkg/backends/clickhouse/clickhouse_test.go | 4 +- pkg/backends/healthcheck/healthcheck.go | 5 +- pkg/backends/healthcheck/healthcheck_test.go | 19 +- pkg/backends/healthcheck/target.go | 8 +- pkg/backends/healthcheck/target_test.go | 1 + pkg/backends/influxdb/influxdb_test.go | 4 +- pkg/backends/influxdb/model/marshal.go | 4 +- pkg/backends/influxdb/model/marshal_test.go | 4 +- pkg/backends/irondb/handler_caql_test.go | 7 +- pkg/backends/irondb/handler_fetch_test.go | 7 +- pkg/backends/irondb/handler_histogram_test.go | 8 +- pkg/backends/irondb/handler_rollup_test.go | 8 +- pkg/backends/irondb/irondb_test.go | 4 +- pkg/backends/irondb/model/model.go | 6 +- pkg/backends/irondb/url_test.go | 8 +- pkg/backends/options/options_test.go | 20 +- pkg/backends/prometheus/model/alerts.go | 4 +- pkg/backends/prometheus/model/alerts_test.go | 29 +- pkg/backends/prometheus/model/labels.go | 2 +- pkg/backends/prometheus/model/labels_test.go | 10 +- pkg/backends/prometheus/model/series.go | 2 +- pkg/backends/prometheus/model/series_test.go | 10 +- pkg/backends/prometheus/model/vector.go | 6 +- pkg/backends/prometheus/model/vector_test.go | 10 +- pkg/backends/prometheus/prometheus_test.go | 11 +- pkg/backends/prometheus/transformations.go | 2 +- .../prometheus/transformations_test.go | 5 +- pkg/backends/prometheus/url_test.go | 3 +- pkg/cache/badger/badger.go | 20 +- pkg/cache/badger/badger_test.go | 18 +- pkg/cache/bbolt/bbolt.go | 24 +- pkg/cache/bbolt/bbolt_test.go | 26 +- pkg/cache/filesystem/filesystem.go | 22 +- pkg/cache/filesystem/filesystem_test.go | 22 +- pkg/cache/index/index.go | 32 +- pkg/cache/index/index_test.go | 4 +- pkg/cache/memory/memory.go | 12 +- pkg/cache/memory/memory_test.go | 24 +- pkg/cache/redis/redis.go | 23 +- pkg/cache/redis/redis_test.go | 10 +- pkg/cache/registration/registration.go | 5 +- pkg/cache/registration/registration_test.go | 4 +- pkg/config/reload/reload.go | 4 +- pkg/httpserver/httpserver.go | 37 +- pkg/httpserver/listeners.go | 26 +- pkg/httpserver/signal/signal.go | 13 +- pkg/httpserver/signal/signal_test.go | 3 +- pkg/observability/logging/level/level.go | 35 + pkg/observability/logging/logging.go | 601 ++++++++---------- pkg/observability/logging/logging_test.go | 149 +---- .../tracing/registration/registration.go | 15 +- .../tracing/registration/registration_test.go | 26 +- pkg/parsing/run_state.go | 10 +- pkg/proxy/context/resources.go | 4 +- pkg/proxy/engines/access_logs.go | 14 +- pkg/proxy/engines/access_logs_test.go | 16 +- pkg/proxy/engines/cache.go | 15 +- pkg/proxy/engines/client_test.go | 79 --- pkg/proxy/engines/deltaproxycache.go | 39 +- pkg/proxy/engines/deltaproxycache_test.go | 6 +- pkg/proxy/engines/document.go | 8 +- pkg/proxy/engines/httpproxy.go | 16 +- pkg/proxy/engines/httpproxy_test.go | 7 +- pkg/proxy/engines/key.go | 1 + pkg/proxy/engines/key_test.go | 10 +- pkg/proxy/engines/objectproxycache.go | 9 +- pkg/proxy/engines/proxy_request.go | 8 +- pkg/proxy/engines/proxy_request_test.go | 19 +- pkg/proxy/engines/revalidation_status.go | 8 - pkg/proxy/handlers/local_test.go | 9 +- pkg/proxy/handlers/purge.go | 5 +- pkg/proxy/handlers/reload.go | 11 +- pkg/proxy/handlers/reload_test.go | 7 +- pkg/proxy/listener/listener.go | 34 +- pkg/proxy/listener/listener_test.go | 17 +- pkg/proxy/request/resources.go | 7 +- pkg/proxy/request/resources_test.go | 10 +- pkg/routing/routing.go | 39 +- pkg/testutil/testing.go | 8 +- pkg/timeseries/timerangequery.go | 2 +- pkg/util/middleware/config_context.go | 9 +- vendor/github.com/go-kit/log/.gitignore | 15 - vendor/github.com/go-kit/log/LICENSE | 21 - vendor/github.com/go-kit/log/README.md | 156 ----- vendor/github.com/go-kit/log/doc.go | 116 ---- vendor/github.com/go-kit/log/json_logger.go | 91 --- vendor/github.com/go-kit/log/level/doc.go | 33 - vendor/github.com/go-kit/log/level/level.go | 256 -------- vendor/github.com/go-kit/log/log.go | 179 ------ vendor/github.com/go-kit/log/logfmt_logger.go | 62 -- vendor/github.com/go-kit/log/nop_logger.go | 8 - vendor/github.com/go-kit/log/staticcheck.conf | 1 - vendor/github.com/go-kit/log/stdlib.go | 151 ----- vendor/github.com/go-kit/log/sync.go | 113 ---- vendor/github.com/go-kit/log/value.go | 110 ---- vendor/github.com/go-logfmt/logfmt/.gitignore | 1 - .../github.com/go-logfmt/logfmt/CHANGELOG.md | 82 --- vendor/github.com/go-logfmt/logfmt/LICENSE | 22 - vendor/github.com/go-logfmt/logfmt/README.md | 41 -- vendor/github.com/go-logfmt/logfmt/decode.go | 254 -------- vendor/github.com/go-logfmt/logfmt/doc.go | 6 - vendor/github.com/go-logfmt/logfmt/encode.go | 322 ---------- .../github.com/go-logfmt/logfmt/jsonstring.go | 277 -------- vendor/github.com/go-stack/stack/LICENSE.md | 21 - vendor/github.com/go-stack/stack/README.md | 38 -- vendor/github.com/go-stack/stack/stack.go | 400 ------------ .../otel/exporters/zipkin/zipkin.go | 4 +- vendor/modules.txt | 10 - 113 files changed, 829 insertions(+), 3775 deletions(-) create mode 100644 pkg/observability/logging/level/level.go delete mode 100644 vendor/github.com/go-kit/log/.gitignore delete mode 100644 vendor/github.com/go-kit/log/LICENSE delete mode 100644 vendor/github.com/go-kit/log/README.md delete mode 100644 vendor/github.com/go-kit/log/doc.go delete mode 100644 vendor/github.com/go-kit/log/json_logger.go delete mode 100644 vendor/github.com/go-kit/log/level/doc.go delete mode 100644 vendor/github.com/go-kit/log/level/level.go delete mode 100644 vendor/github.com/go-kit/log/log.go delete mode 100644 vendor/github.com/go-kit/log/logfmt_logger.go delete mode 100644 vendor/github.com/go-kit/log/nop_logger.go delete mode 100644 vendor/github.com/go-kit/log/staticcheck.conf delete mode 100644 vendor/github.com/go-kit/log/stdlib.go delete mode 100644 vendor/github.com/go-kit/log/sync.go delete mode 100644 vendor/github.com/go-kit/log/value.go delete mode 100644 vendor/github.com/go-logfmt/logfmt/.gitignore delete mode 100644 vendor/github.com/go-logfmt/logfmt/CHANGELOG.md delete mode 100644 vendor/github.com/go-logfmt/logfmt/LICENSE delete mode 100644 vendor/github.com/go-logfmt/logfmt/README.md delete mode 100644 vendor/github.com/go-logfmt/logfmt/decode.go delete mode 100644 vendor/github.com/go-logfmt/logfmt/doc.go delete mode 100644 vendor/github.com/go-logfmt/logfmt/encode.go delete mode 100644 vendor/github.com/go-logfmt/logfmt/jsonstring.go delete mode 100644 vendor/github.com/go-stack/stack/LICENSE.md delete mode 100644 vendor/github.com/go-stack/stack/README.md delete mode 100644 vendor/github.com/go-stack/stack/stack.go diff --git a/go.mod b/go.mod index e02dc6338..22922754f 100644 --- a/go.mod +++ b/go.mod @@ -8,9 +8,7 @@ require ( github.com/alicebob/miniredis v2.5.0+incompatible github.com/andybalholm/brotli v1.1.0 github.com/dgraph-io/badger v1.6.2 - github.com/go-kit/log v0.2.1 github.com/go-redis/redis v6.15.9+incompatible - github.com/go-stack/stack v1.8.1 github.com/golang/snappy v0.0.4 github.com/influxdata/influxdb v1.11.6 github.com/influxdata/influxql v1.2.0 @@ -41,7 +39,6 @@ require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/dustin/go-humanize v1.0.1 // indirect - github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/golang/glog v1.2.2 // indirect diff --git a/go.sum b/go.sum index 0236f4c0b..c5e73e885 100644 --- a/go.sum +++ b/go.sum @@ -99,13 +99,9 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= -github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= -github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -114,8 +110,6 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg= github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= -github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= diff --git a/pkg/backends/alb/response_merge_test.go b/pkg/backends/alb/response_merge_test.go index 629de7b82..2f27ae28a 100644 --- a/pkg/backends/alb/response_merge_test.go +++ b/pkg/backends/alb/response_merge_test.go @@ -24,11 +24,14 @@ import ( "github.com/trickstercache/trickster/v2/pkg/backends/alb/pool" "github.com/trickstercache/trickster/v2/pkg/backends/healthcheck" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" "github.com/trickstercache/trickster/v2/pkg/proxy/request" "github.com/trickstercache/trickster/v2/pkg/proxy/response/merge" tu "github.com/trickstercache/trickster/v2/pkg/testutil" ) +var testLogger = logging.NoopLogger() + func testMergeFunc(w http.ResponseWriter, r *http.Request, rgs merge.ResponseGates) { } @@ -36,7 +39,7 @@ func testMergeFunc(w http.ResponseWriter, r *http.Request, rgs merge.ResponseGat func TestHandleResponseMerge(t *testing.T) { r, _ := http.NewRequest("GET", "http://trickstercache.org/", nil) - rsc := request.NewResources(nil, nil, nil, nil, nil, nil, nil) + rsc := request.NewResources(nil, nil, nil, nil, nil, nil, testLogger) rsc.ResponseMergeFunc = testMergeFunc rsc.IsMergeMember = true r = request.SetResources(r, rsc) diff --git a/pkg/backends/backend_test.go b/pkg/backends/backend_test.go index 8ddae1ff4..edece4441 100644 --- a/pkg/backends/backend_test.go +++ b/pkg/backends/backend_test.go @@ -24,7 +24,7 @@ import ( bo "github.com/trickstercache/trickster/v2/pkg/backends/options" cr "github.com/trickstercache/trickster/v2/pkg/cache/registration" "github.com/trickstercache/trickster/v2/pkg/config" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" ) func TestConfiguration(t *testing.T) { @@ -44,7 +44,7 @@ func TestCache(t *testing.T) { t.Fatalf("Could not load configuration: %s", err.Error()) } - caches := cr.LoadCachesFromConfig(conf, tl.ConsoleLogger("error")) + caches := cr.LoadCachesFromConfig(conf, logging.ConsoleLogger("error")) defer cr.CloseCaches(caches) cache, ok := caches["default"] if !ok { diff --git a/pkg/backends/backends.go b/pkg/backends/backends.go index ff2305242..a8e1289ca 100644 --- a/pkg/backends/backends.go +++ b/pkg/backends/backends.go @@ -22,6 +22,7 @@ import ( "github.com/trickstercache/trickster/v2/pkg/backends/healthcheck" bo "github.com/trickstercache/trickster/v2/pkg/backends/options" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" ) // Backends represents a map of Backends keyed by Name @@ -29,7 +30,7 @@ type Backends map[string]Backend // StartHealthChecks iterates the backends to fully configure health checkers // and start up any intervaled health checks -func (b Backends) StartHealthChecks(logger interface{}) (healthcheck.HealthChecker, error) { +func (b Backends) StartHealthChecks(logger logging.Logger) (healthcheck.HealthChecker, error) { hc := healthcheck.New() for k, c := range b { bo := c.Configuration() diff --git a/pkg/backends/clickhouse/clickhouse_test.go b/pkg/backends/clickhouse/clickhouse_test.go index c378190b5..63e39745c 100644 --- a/pkg/backends/clickhouse/clickhouse_test.go +++ b/pkg/backends/clickhouse/clickhouse_test.go @@ -26,7 +26,7 @@ import ( bo "github.com/trickstercache/trickster/v2/pkg/backends/options" cr "github.com/trickstercache/trickster/v2/pkg/cache/registration" "github.com/trickstercache/trickster/v2/pkg/config" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" ) var testModeler = model.NewModeler() @@ -60,7 +60,7 @@ func TestNewClient(t *testing.T) { t.Fatalf("Could not load configuration: %s", err.Error()) } - caches := cr.LoadCachesFromConfig(conf, tl.ConsoleLogger("error")) + caches := cr.LoadCachesFromConfig(conf, logging.ConsoleLogger("error")) defer cr.CloseCaches(caches) cache, ok := caches["default"] if !ok { diff --git a/pkg/backends/healthcheck/healthcheck.go b/pkg/backends/healthcheck/healthcheck.go index 91d930c20..52261645b 100644 --- a/pkg/backends/healthcheck/healthcheck.go +++ b/pkg/backends/healthcheck/healthcheck.go @@ -22,11 +22,12 @@ import ( "time" ho "github.com/trickstercache/trickster/v2/pkg/backends/healthcheck/options" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" ) // HealthChecker defines the Health Checker interface type HealthChecker interface { - Register(string, string, *ho.Options, *http.Client, interface{}) (*Status, error) + Register(string, string, *ho.Options, *http.Client, logging.Logger) (*Status, error) Unregister(string) Status(string) *Status Statuses() StatusLookup @@ -66,7 +67,7 @@ func (hc *healthChecker) Shutdown() { } func (hc *healthChecker) Register(name, description string, o *ho.Options, - client *http.Client, logger interface{}) (*Status, error) { + client *http.Client, logger logging.Logger) (*Status, error) { if o == nil { return nil, ho.ErrNoOptionsProvided } diff --git a/pkg/backends/healthcheck/healthcheck_test.go b/pkg/backends/healthcheck/healthcheck_test.go index 4fa19d239..73b58a6c8 100644 --- a/pkg/backends/healthcheck/healthcheck_test.go +++ b/pkg/backends/healthcheck/healthcheck_test.go @@ -22,8 +22,11 @@ import ( "testing" ho "github.com/trickstercache/trickster/v2/pkg/backends/healthcheck/options" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" ) +var testLogger = logging.NoopLogger() + func TestNew(t *testing.T) { hc := New() @@ -58,23 +61,23 @@ func TestRegister(t *testing.T) { hc := New().(*healthChecker) o := ho.New() o.IntervalMS = 500 - _, err := hc.Register("test", "test", o, http.DefaultClient, nil) + _, err := hc.Register("test", "test", o, http.DefaultClient, testLogger) if err != nil { t.Error(err) } target := hc.targets["test"] target.Start() target.Stop() - _, err = hc.Register("test", "test", o, http.DefaultClient, nil) + _, err = hc.Register("test", "test", o, http.DefaultClient, testLogger) if err != nil { t.Error(err) } o.Body = "test-body" - _, err = hc.Register("test", "test", o, http.DefaultClient, nil) + _, err = hc.Register("test", "test", o, http.DefaultClient, testLogger) if err != nil { t.Error(err) } - _, err = hc.Register("test", "test", nil, http.DefaultClient, nil) + _, err = hc.Register("test", "test", nil, http.DefaultClient, testLogger) if err != ho.ErrNoOptionsProvided { t.Errorf("expected %v got %v", ho.ErrNoOptionsProvided, err) } @@ -84,7 +87,7 @@ func TestUnregister(t *testing.T) { hc := New().(*healthChecker) o := ho.New() o.IntervalMS = 500 - _, err := hc.Register("test", "test", o, http.DefaultClient, nil) + _, err := hc.Register("test", "test", o, http.DefaultClient, testLogger) if err != nil { t.Error(err) } @@ -99,7 +102,7 @@ func TestStatus(t *testing.T) { hc := New().(*healthChecker) o := ho.New() o.IntervalMS = 500 - _, err := hc.Register("test", "test", o, http.DefaultClient, nil) + _, err := hc.Register("test", "test", o, http.DefaultClient, testLogger) if err != nil { t.Error(err) } @@ -125,7 +128,7 @@ func TestStatuses(t *testing.T) { hc := New().(*healthChecker) o := ho.New() o.IntervalMS = 500 - _, err := hc.Register("test", "test", o, http.DefaultClient, nil) + _, err := hc.Register("test", "test", o, http.DefaultClient, testLogger) if err != nil { t.Error(err) } @@ -144,7 +147,7 @@ func TestHealthCheckerProbe(t *testing.T) { ts := newTestServer(200, "OK", map[string]string{}) r, _ := http.NewRequest("GET", ts.URL+"/", nil) - _, err := hc.Register("test", "test", o, http.DefaultClient, nil) + _, err := hc.Register("test", "test", o, http.DefaultClient, testLogger) if err != nil { t.Error(err) } diff --git a/pkg/backends/healthcheck/target.go b/pkg/backends/healthcheck/target.go index bbf722487..d73f78470 100644 --- a/pkg/backends/healthcheck/target.go +++ b/pkg/backends/healthcheck/target.go @@ -54,7 +54,7 @@ type target struct { eb string eh http.Header ec []int - logger interface{} + logger logging.Logger isInLoop bool } @@ -66,7 +66,7 @@ type DemandProbe func(w http.ResponseWriter) func newTarget(ctx context.Context, name, description string, o *ho.Options, client *http.Client, - logger interface{}) (*target, error) { + logger logging.Logger) (*target, error) { if o == nil { return nil, ho.ErrNoOptionsProvided @@ -225,7 +225,7 @@ func (t *target) probe() { t.status.failingSince = time.Now() t.status.Set(-1) t.ks = -1 - logging.Info(t.logger, "hc status changed", + t.logger.Info("hc status changed", logging.Pairs{"targetName": t.name, "status": "failed", "detail": t.status.detail, "threshold": t.failureThreshold}) } else if passed && t.ks != 1 && (successCnt == t.recoveryThreshold || t.ks == 0) { @@ -233,7 +233,7 @@ func (t *target) probe() { t.status.Set(1) t.ks = 1 t.status.detail = "" // this is only populated with failure details, so it is cleared upon recovery - logging.Info(t.logger, "hc status changed", + t.logger.Info("hc status changed", logging.Pairs{"targetName": t.name, "status": "available", "threshold": t.recoveryThreshold}) } diff --git a/pkg/backends/healthcheck/target_test.go b/pkg/backends/healthcheck/target_test.go index 12e9cadba..dc62900e0 100644 --- a/pkg/backends/healthcheck/target_test.go +++ b/pkg/backends/healthcheck/target_test.go @@ -224,6 +224,7 @@ func TestProbe(t *testing.T) { baseRequest: r, httpClient: ts.Client(), ec: []int{200}, + logger: testLogger, } target.probe() if target.successConsecutiveCnt.Load() != 1 { diff --git a/pkg/backends/influxdb/influxdb_test.go b/pkg/backends/influxdb/influxdb_test.go index d64a3845b..36897e219 100644 --- a/pkg/backends/influxdb/influxdb_test.go +++ b/pkg/backends/influxdb/influxdb_test.go @@ -24,7 +24,7 @@ import ( bo "github.com/trickstercache/trickster/v2/pkg/backends/options" cr "github.com/trickstercache/trickster/v2/pkg/cache/registration" "github.com/trickstercache/trickster/v2/pkg/config" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" ) var testModeler = model.NewModeler() @@ -58,7 +58,7 @@ func TestNewClient(t *testing.T) { t.Fatalf("Could not load configuration: %s", err.Error()) } - caches := cr.LoadCachesFromConfig(conf, tl.ConsoleLogger("error")) + caches := cr.LoadCachesFromConfig(conf, logging.ConsoleLogger("error")) defer cr.CloseCaches(caches) cache, ok := caches["default"] if !ok { diff --git a/pkg/backends/influxdb/model/marshal.go b/pkg/backends/influxdb/model/marshal.go index 01d123840..35e167279 100644 --- a/pkg/backends/influxdb/model/marshal.go +++ b/pkg/backends/influxdb/model/marshal.go @@ -73,7 +73,7 @@ func writeEpochTime(w io.Writer, epoch epoch.Epoch, m int64) { w.Write([]byte(strconv.FormatInt(int64(epoch)/m, 10))) } -func writeValue(w io.Writer, v interface{}, nilVal string) { +func writeValue(w io.Writer, v any, nilVal string) { if v == nil { w.Write([]byte(nilVal)) } @@ -91,7 +91,7 @@ func writeValue(w io.Writer, v interface{}, nilVal string) { } } -func writeCSVValue(w io.Writer, v interface{}, nilVal string) { +func writeCSVValue(w io.Writer, v any, nilVal string) { if v == nil { w.Write([]byte(nilVal)) } diff --git a/pkg/backends/influxdb/model/marshal_test.go b/pkg/backends/influxdb/model/marshal_test.go index 7e8cc57ad..f43c7ae57 100644 --- a/pkg/backends/influxdb/model/marshal_test.go +++ b/pkg/backends/influxdb/model/marshal_test.go @@ -114,7 +114,7 @@ func TestWriteEpochTime(t *testing.T) { func TestWriteValue(t *testing.T) { tests := []struct { - val interface{} + val any nilVal string expectedErr error expectedVal string @@ -175,7 +175,7 @@ func TestWriteValue(t *testing.T) { func TestWriteCSVValue(t *testing.T) { tests := []struct { - val interface{} + val any nilVal string expectedErr error expectedVal string diff --git a/pkg/backends/irondb/handler_caql_test.go b/pkg/backends/irondb/handler_caql_test.go index b8eec3f4b..7a8cefb4c 100644 --- a/pkg/backends/irondb/handler_caql_test.go +++ b/pkg/backends/irondb/handler_caql_test.go @@ -23,10 +23,10 @@ import ( "time" bo "github.com/trickstercache/trickster/v2/pkg/backends/options" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" "github.com/trickstercache/trickster/v2/pkg/proxy/request" - "github.com/trickstercache/trickster/v2/pkg/timeseries" tu "github.com/trickstercache/trickster/v2/pkg/testutil" + "github.com/trickstercache/trickster/v2/pkg/timeseries" ) func TestCAQLHandler(t *testing.T) { @@ -88,7 +88,8 @@ func TestCaqlHandlerSetExtent(t *testing.T) { t.Error(err) } - r = request.SetResources(r, request.NewResources(cfg, nil, nil, nil, client, nil, tl.ConsoleLogger("error"))) + r = request.SetResources(r, request.NewResources(cfg, nil, nil, nil, client, + nil, logging.ConsoleLogger("error"))) now := time.Now() then := now.Add(-5 * time.Hour) diff --git a/pkg/backends/irondb/handler_fetch_test.go b/pkg/backends/irondb/handler_fetch_test.go index 405b29de6..573ac9d42 100644 --- a/pkg/backends/irondb/handler_fetch_test.go +++ b/pkg/backends/irondb/handler_fetch_test.go @@ -24,10 +24,10 @@ import ( "time" bo "github.com/trickstercache/trickster/v2/pkg/backends/options" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" "github.com/trickstercache/trickster/v2/pkg/proxy/request" - "github.com/trickstercache/trickster/v2/pkg/timeseries" tu "github.com/trickstercache/trickster/v2/pkg/testutil" + "github.com/trickstercache/trickster/v2/pkg/timeseries" ) func TestFetchHandler(t *testing.T) { @@ -112,7 +112,8 @@ func TestFetchHandlerSetExtent(t *testing.T) { t.Error(err) } - r = request.SetResources(r, request.NewResources(o, nil, nil, nil, client, nil, tl.ConsoleLogger("error"))) + r = request.SetResources(r, request.NewResources(o, nil, nil, nil, client, + nil, logging.ConsoleLogger("error"))) now := time.Now() then := now.Add(-5 * time.Hour) diff --git a/pkg/backends/irondb/handler_histogram_test.go b/pkg/backends/irondb/handler_histogram_test.go index d8ce10747..3666d51ec 100644 --- a/pkg/backends/irondb/handler_histogram_test.go +++ b/pkg/backends/irondb/handler_histogram_test.go @@ -24,11 +24,11 @@ import ( "time" bo "github.com/trickstercache/trickster/v2/pkg/backends/options" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" "github.com/trickstercache/trickster/v2/pkg/proxy/errors" "github.com/trickstercache/trickster/v2/pkg/proxy/request" - "github.com/trickstercache/trickster/v2/pkg/timeseries" tu "github.com/trickstercache/trickster/v2/pkg/testutil" + "github.com/trickstercache/trickster/v2/pkg/timeseries" ) func TestHistogramHandler(t *testing.T) { @@ -204,7 +204,7 @@ func TestHistogramHandlerSetExtent(t *testing.T) { } r = request.SetResources(r, - request.NewResources(o, nil, nil, nil, client, nil, tl.ConsoleLogger("error"))) + request.NewResources(o, nil, nil, nil, client, nil, logging.ConsoleLogger("error"))) now := time.Now() then := now.Add(-5 * time.Hour) @@ -241,7 +241,7 @@ func TestHistogramHandlerFastForwardRequestError(t *testing.T) { t.Error(err) } - rsc := request.NewResources(o, nil, nil, nil, client, nil, tl.ConsoleLogger("error")) + rsc := request.NewResources(o, nil, nil, nil, client, nil, logging.ConsoleLogger("error")) r = request.SetResources(r, rsc) r.URL.Path = "/histogram/x/900/300/00112233-4455-6677-8899-aabbccddeeff/metric" diff --git a/pkg/backends/irondb/handler_rollup_test.go b/pkg/backends/irondb/handler_rollup_test.go index 48a498301..ae45c734f 100644 --- a/pkg/backends/irondb/handler_rollup_test.go +++ b/pkg/backends/irondb/handler_rollup_test.go @@ -24,11 +24,11 @@ import ( "time" bo "github.com/trickstercache/trickster/v2/pkg/backends/options" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" "github.com/trickstercache/trickster/v2/pkg/proxy/errors" "github.com/trickstercache/trickster/v2/pkg/proxy/request" - "github.com/trickstercache/trickster/v2/pkg/timeseries" tu "github.com/trickstercache/trickster/v2/pkg/testutil" + "github.com/trickstercache/trickster/v2/pkg/timeseries" ) func TestRollupHandler(t *testing.T) { @@ -88,7 +88,7 @@ func TestRollupHandlerSetExtent(t *testing.T) { t.Error(err) } - r = request.SetResources(r, request.NewResources(o, nil, nil, nil, client, nil, tl.ConsoleLogger("error"))) + r = request.SetResources(r, request.NewResources(o, nil, nil, nil, client, nil, logging.ConsoleLogger("error"))) now := time.Now() then := now.Add(-5 * time.Hour) @@ -119,7 +119,7 @@ func TestRollupHandlerParseTimeRangeQuery(t *testing.T) { t.Error(err) } - r = request.SetResources(r, request.NewResources(o, nil, nil, nil, client, nil, tl.ConsoleLogger("error"))) + r = request.SetResources(r, request.NewResources(o, nil, nil, nil, client, nil, logging.ConsoleLogger("error"))) // case where everything is good r.URL.RawQuery = "start_ts=0&end_ts=900&rollup_span=300s&type=average" diff --git a/pkg/backends/irondb/irondb_test.go b/pkg/backends/irondb/irondb_test.go index 491d07098..be46061e3 100644 --- a/pkg/backends/irondb/irondb_test.go +++ b/pkg/backends/irondb/irondb_test.go @@ -23,7 +23,7 @@ import ( bo "github.com/trickstercache/trickster/v2/pkg/backends/options" cr "github.com/trickstercache/trickster/v2/pkg/cache/registration" "github.com/trickstercache/trickster/v2/pkg/config" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" ) func TestIRONdbClientInterfacing(t *testing.T) { @@ -54,7 +54,7 @@ func TestNewClient(t *testing.T) { t.Fatalf("Could not load configuration: %s", err.Error()) } - caches := cr.LoadCachesFromConfig(conf, tl.ConsoleLogger("error")) + caches := cr.LoadCachesFromConfig(conf, logging.ConsoleLogger("error")) defer cr.CloseCaches(caches) cache, ok := caches["default"] if !ok { diff --git a/pkg/backends/irondb/model/model.go b/pkg/backends/irondb/model/model.go index 392b96763..92afa759a 100644 --- a/pkg/backends/irondb/model/model.go +++ b/pkg/backends/irondb/model/model.go @@ -116,12 +116,12 @@ func (se *SeriesEnvelope) SetVolatileExtents(e timeseries.ExtentList) { type DataPoint struct { Time time.Time Step uint32 - Value interface{} + Value any } // MarshalJSON encodes a data point value into a JSON byte slice. func (dp *DataPoint) MarshalJSON() ([]byte, error) { - v := []interface{}{} + v := []any{} tn := float64(0) fv, err := strconv.ParseFloat(common.FormatTimestamp(dp.Time, true), 64) if err == nil { @@ -139,7 +139,7 @@ func (dp *DataPoint) MarshalJSON() ([]byte, error) { // UnmarshalJSON decodes a JSON byte slice into this data point value. func (dp *DataPoint) UnmarshalJSON(b []byte) error { - v := []interface{}{} + v := []any{} err := json.Unmarshal(b, &v) if err != nil { return err diff --git a/pkg/backends/irondb/url_test.go b/pkg/backends/irondb/url_test.go index b8ea7e17f..f03fcaf5a 100644 --- a/pkg/backends/irondb/url_test.go +++ b/pkg/backends/irondb/url_test.go @@ -28,7 +28,7 @@ import ( "github.com/trickstercache/trickster/v2/pkg/backends/irondb/common" "github.com/trickstercache/trickster/v2/pkg/config" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" "github.com/trickstercache/trickster/v2/pkg/proxy/errors" po "github.com/trickstercache/trickster/v2/pkg/proxy/paths/options" "github.com/trickstercache/trickster/v2/pkg/proxy/request" @@ -62,7 +62,7 @@ func TestSetExtent(t *testing.T) { client.makeExtentSetters() pcs := client.DefaultPathConfigs(o) - rsc := request.NewResources(o, nil, nil, nil, client, nil, tl.ConsoleLogger("error")) + rsc := request.NewResources(o, nil, nil, nil, client, nil, logging.ConsoleLogger("error")) cases := []struct { handler string @@ -230,7 +230,7 @@ func TestFastForwardURL(t *testing.T) { pcs := client.DefaultPathConfigs(o) - rsc := request.NewResources(o, nil, nil, nil, client, nil, tl.ConsoleLogger("error")) + rsc := request.NewResources(o, nil, nil, nil, client, nil, logging.ConsoleLogger("error")) cases := []struct { handler string @@ -327,7 +327,7 @@ func TestParseTimerangeQuery(t *testing.T) { r, _ := http.NewRequest(http.MethodGet, "http://127.0.0.1/", nil) r = request.SetResources(r, request.NewResources(client.Configuration(), &po.Options{}, - nil, nil, client, nil, tl.ConsoleLogger("error"))) + nil, nil, client, nil, logging.ConsoleLogger("error"))) _, _, _, err = client.ParseTimeRangeQuery(r) if err == nil || err != expected { diff --git a/pkg/backends/options/options_test.go b/pkg/backends/options/options_test.go index 98e58d83b..22b5fd335 100644 --- a/pkg/backends/options/options_test.go +++ b/pkg/backends/options/options_test.go @@ -75,7 +75,7 @@ func TestClone(t *testing.T) { o := New() o.Hosts = []string{"test"} o.CacheName = "test" - o.CompressibleTypes = map[string]interface{}{"test": nil} + o.CompressibleTypes = map[string]any{"test": nil} o.Paths = map[string]*po.Options{"test": p} o.NegativeCache = map[int]time.Duration{1: 1} o.HealthCheck = &ho.Options{} @@ -210,7 +210,7 @@ func TestValidate(t *testing.T) { to *testOptions loc *string val string - expected interface{} + expected any }{ { // 0 - invalid negative cache name to: to, @@ -282,7 +282,7 @@ func TestValidate(t *testing.T) { tests2 := []struct { to *testOptions sw []intSwapper - expected interface{} + expected any }{ { // case 0 - MaxShardSizeMS > 0 and MaxShardSizePoints > 0 are mutually exclusive to: to, @@ -356,12 +356,12 @@ func TestSetDefaults(t *testing.T) { backends := Lookup{o.Name: o} - _, err = SetDefaults("test", o, o.md, nil, backends, map[string]interface{}{}) + _, err = SetDefaults("test", o, o.md, nil, backends, map[string]any{}) if err != nil { t.Error(err) } - _, err = SetDefaults("test", o, nil, nil, backends, map[string]interface{}{}) + _, err = SetDefaults("test", o, nil, nil, backends, map[string]any{}) if err != ErrInvalidMetadata { t.Error("expected invalid metadata, got", err) } @@ -371,13 +371,13 @@ func TestSetDefaults(t *testing.T) { t.Error(err) } - _, err = SetDefaults("test", o2, o2.md, nil, backends, map[string]interface{}{}) + _, err = SetDefaults("test", o2, o2.md, nil, backends, map[string]any{}) if err != nil { t.Error(err) } o.Paths["series"].ReqRewriterName = "invalid" - _, err = SetDefaults("test", o, o.md, nil, backends, map[string]interface{}{}) + _, err = SetDefaults("test", o, o.md, nil, backends, map[string]any{}) if err == nil { t.Error("expected error for invalid rewriter name") } @@ -388,13 +388,13 @@ func TestSetDefaults(t *testing.T) { } _, err = SetDefaults("test", o2, o2.md, map[string]rewriter.RewriteInstructions{"test": nil}, - backends, map[string]interface{}{}) + backends, map[string]any{}) if err != nil { t.Error(err) } _, err = SetDefaults("test", o2, o2.md, map[string]rewriter.RewriteInstructions{"not-test": nil}, - backends, map[string]interface{}{}) + backends, map[string]any{}) if err == nil { t.Error("expected error for invalid rewriter name") } @@ -405,7 +405,7 @@ func TestSetDefaults(t *testing.T) { } _, err = SetDefaults("test", o2, o2.md, nil, - backends, map[string]interface{}{}) + backends, map[string]any{}) if err != nil { t.Error(err) } diff --git a/pkg/backends/prometheus/model/alerts.go b/pkg/backends/prometheus/model/alerts.go index b6b4db8b5..6f6bff109 100644 --- a/pkg/backends/prometheus/model/alerts.go +++ b/pkg/backends/prometheus/model/alerts.go @@ -24,12 +24,12 @@ import ( "net/http" "sort" + "github.com/trickstercache/trickster/v2/pkg/checksum/fnv" "github.com/trickstercache/trickster/v2/pkg/observability/logging" "github.com/trickstercache/trickster/v2/pkg/proxy/handlers" "github.com/trickstercache/trickster/v2/pkg/proxy/headers" "github.com/trickstercache/trickster/v2/pkg/proxy/response/merge" "github.com/trickstercache/trickster/v2/pkg/timeseries/dataset" - "github.com/trickstercache/trickster/v2/pkg/checksum/fnv" ) // WFAlerts is the Wire Format Document for the /alerts endpoint @@ -130,7 +130,7 @@ func MergeAndWriteAlerts(w http.ResponseWriter, r *http.Request, rgs merge.Respo a1 := &WFAlerts{} err := json.Unmarshal(rg.Body(), &a1) if err != nil { - logging.Error(rg.Resources.Logger, "alerts unmarshaling error", + rg.Resources.Logger.Error("alerts unmarshaling error", logging.Pairs{"provider": "prometheus", "detail": err.Error()}) continue } diff --git a/pkg/backends/prometheus/model/alerts_test.go b/pkg/backends/prometheus/model/alerts_test.go index dcfde3878..719482565 100644 --- a/pkg/backends/prometheus/model/alerts_test.go +++ b/pkg/backends/prometheus/model/alerts_test.go @@ -24,10 +24,14 @@ import ( "strconv" "testing" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" "github.com/trickstercache/trickster/v2/pkg/proxy/request" "github.com/trickstercache/trickster/v2/pkg/proxy/response/merge" ) +var testLogger = logging.NoopLogger() +var testResources = request.NewResources(nil, nil, nil, nil, nil, nil, testLogger) + func TestCalculateHash(t *testing.T) { a := &WFAlert{ @@ -81,6 +85,11 @@ func TestMerge(t *testing.T) { } +func newTestReq() *http.Request { + r, _ := http.NewRequest(http.MethodGet, "/", nil) + return r +} + func TestMergeAndWriteAlerts(t *testing.T) { var nilRG *merge.ResponseGate @@ -91,22 +100,22 @@ func TestMergeAndWriteAlerts(t *testing.T) { expCode int }{ { - nil, + newTestReq(), nil, http.StatusBadGateway, }, { - nil, + newTestReq(), merge.ResponseGates{nilRG}, http.StatusBadGateway, }, { - nil, + newTestReq(), testResponseGates1(), http.StatusOK, }, { - nil, + newTestReq(), testResponseGates2(), http.StatusBadRequest, }, @@ -115,7 +124,7 @@ func TestMergeAndWriteAlerts(t *testing.T) { for i, test := range tests { t.Run(strconv.Itoa(i), func(t *testing.T) { w := httptest.NewRecorder() - MergeAndWriteAlerts(w, test.r, test.rgs) + MergeAndWriteAlerts(w, request.SetResources(test.r, testResources), test.rgs) if w.Code != test.expCode { t.Errorf("expected %d got %d", test.expCode, w.Code) } @@ -130,7 +139,7 @@ func testResponseGates1() merge.ResponseGates { {"state":"test","labels":{},"annotations":{},"value":"x","activeAt":"y"} ]}}`) closer1 := io.NopCloser(bytes.NewReader(b1)) - rsc1 := request.NewResources(nil, nil, nil, nil, nil, nil, nil) + rsc1 := request.NewResources(nil, nil, nil, nil, nil, nil, testLogger) rsc1.Response = &http.Response{ Body: closer1, StatusCode: 200, @@ -144,7 +153,7 @@ func testResponseGates1() merge.ResponseGates { b2bad := []byte(`{"stat`) closer2 := io.NopCloser(bytes.NewReader(b2bad)) - rsc2 := request.NewResources(nil, nil, nil, nil, nil, nil, nil) + rsc2 := request.NewResources(nil, nil, nil, nil, nil, nil, testLogger) rsc2.Response = &http.Response{ Body: closer2, StatusCode: 200, @@ -158,7 +167,7 @@ func testResponseGates1() merge.ResponseGates { b3 := []byte(`{"status":"success","data":{"alerts":[]}}`) closer3 := io.NopCloser(bytes.NewReader(b3)) - rsc3 := request.NewResources(nil, nil, nil, nil, nil, nil, nil) + rsc3 := request.NewResources(nil, nil, nil, nil, nil, nil, testLogger) rsc3.Response = &http.Response{ Body: closer3, StatusCode: 200, @@ -178,7 +187,7 @@ func testResponseGates2() merge.ResponseGates { b1 := []byte(`{"status":"error","data":{"alerts":[]}}`) closer1 := io.NopCloser(bytes.NewReader(b1)) - rsc1 := request.NewResources(nil, nil, nil, nil, nil, nil, nil) + rsc1 := request.NewResources(nil, nil, nil, nil, nil, nil, testLogger) rsc1.Response = &http.Response{ Body: closer1, StatusCode: 400, @@ -192,7 +201,7 @@ func testResponseGates2() merge.ResponseGates { b2 := []byte(`{"status":"error","data":{"alerts":[]}}`) closer2 := io.NopCloser(bytes.NewReader(b1)) - rsc2 := request.NewResources(nil, nil, nil, nil, nil, nil, nil) + rsc2 := request.NewResources(nil, nil, nil, nil, nil, nil, testLogger) rsc2.Response = &http.Response{ Body: closer2, StatusCode: 400, diff --git a/pkg/backends/prometheus/model/labels.go b/pkg/backends/prometheus/model/labels.go index b823d3120..df7ad391c 100644 --- a/pkg/backends/prometheus/model/labels.go +++ b/pkg/backends/prometheus/model/labels.go @@ -78,7 +78,7 @@ func MergeAndWriteLabelData(w http.ResponseWriter, r *http.Request, rgs merge.Re ld1 := &WFLabelData{} err := json.Unmarshal(rg.Body(), &ld1) if err != nil { - logging.Error(rg.Resources.Logger, "labels unmarshaling error", + rg.Resources.Logger.Error("labels unmarshaling error", logging.Pairs{"provider": "prometheus", "detail": err.Error()}) continue } diff --git a/pkg/backends/prometheus/model/labels_test.go b/pkg/backends/prometheus/model/labels_test.go index 943092d13..9a762f9f1 100644 --- a/pkg/backends/prometheus/model/labels_test.go +++ b/pkg/backends/prometheus/model/labels_test.go @@ -121,7 +121,7 @@ func testResponseGates3() merge.ResponseGates { b1 := []byte(`{"status":"success","data":["test", "trickster"]}`) closer1 := io.NopCloser(bytes.NewReader(b1)) - rsc1 := request.NewResources(nil, nil, nil, nil, nil, nil, nil) + rsc1 := request.NewResources(nil, nil, nil, nil, nil, nil, testLogger) rsc1.Response = &http.Response{ Body: closer1, StatusCode: 200, @@ -135,7 +135,7 @@ func testResponseGates3() merge.ResponseGates { b2bad := []byte(`{"stat`) closer2 := io.NopCloser(bytes.NewReader(b2bad)) - rsc2 := request.NewResources(nil, nil, nil, nil, nil, nil, nil) + rsc2 := request.NewResources(nil, nil, nil, nil, nil, nil, testLogger) rsc2.Response = &http.Response{ Body: closer2, StatusCode: 200, @@ -149,7 +149,7 @@ func testResponseGates3() merge.ResponseGates { b3 := []byte(`{"status":"success","data":["test2", "trickster2"]}`) closer3 := io.NopCloser(bytes.NewReader(b3)) - rsc3 := request.NewResources(nil, nil, nil, nil, nil, nil, nil) + rsc3 := request.NewResources(nil, nil, nil, nil, nil, nil, testLogger) rsc3.Response = &http.Response{ Body: closer3, StatusCode: 200, @@ -169,7 +169,7 @@ func testResponseGates4() merge.ResponseGates { b1 := []byte(`{"status":"error"`) closer1 := io.NopCloser(bytes.NewReader(b1)) - rsc1 := request.NewResources(nil, nil, nil, nil, nil, nil, nil) + rsc1 := request.NewResources(nil, nil, nil, nil, nil, nil, testLogger) rsc1.Response = &http.Response{ Body: closer1, StatusCode: 400, @@ -183,7 +183,7 @@ func testResponseGates4() merge.ResponseGates { b2 := []byte(`{"status":"error","data":["should", "not", "append"]`) closer2 := io.NopCloser(bytes.NewReader(b1)) - rsc2 := request.NewResources(nil, nil, nil, nil, nil, nil, nil) + rsc2 := request.NewResources(nil, nil, nil, nil, nil, nil, testLogger) rsc2.Response = &http.Response{ Body: closer2, StatusCode: 400, diff --git a/pkg/backends/prometheus/model/series.go b/pkg/backends/prometheus/model/series.go index f04becd4b..79a14ce87 100644 --- a/pkg/backends/prometheus/model/series.go +++ b/pkg/backends/prometheus/model/series.go @@ -86,7 +86,7 @@ func MergeAndWriteSeries(w http.ResponseWriter, r *http.Request, rgs merge.Respo s1 := &WFSeries{} err := json.Unmarshal(rg.Body(), &s1) if err != nil { - logging.Error(rg.Resources.Logger, "series unmarshaling error", + rg.Resources.Logger.Error("series unmarshaling error", logging.Pairs{"provider": "prometheus", "detail": err.Error()}) continue } diff --git a/pkg/backends/prometheus/model/series_test.go b/pkg/backends/prometheus/model/series_test.go index d7dfe5485..2d0b10525 100644 --- a/pkg/backends/prometheus/model/series_test.go +++ b/pkg/backends/prometheus/model/series_test.go @@ -177,7 +177,7 @@ func testResponseGates5() merge.ResponseGates { b1 := []byte(`{"status":"success","data":[{"__name__":"test1","instance":"i1","job":"trickster"}]}`) closer1 := io.NopCloser(bytes.NewReader(b1)) - rsc1 := request.NewResources(nil, nil, nil, nil, nil, nil, nil) + rsc1 := request.NewResources(nil, nil, nil, nil, nil, nil, testLogger) rsc1.Response = &http.Response{ Body: closer1, StatusCode: 200, @@ -191,7 +191,7 @@ func testResponseGates5() merge.ResponseGates { b2bad := []byte(`{"stat`) closer2 := io.NopCloser(bytes.NewReader(b2bad)) - rsc2 := request.NewResources(nil, nil, nil, nil, nil, nil, nil) + rsc2 := request.NewResources(nil, nil, nil, nil, nil, nil, testLogger) rsc2.Response = &http.Response{ Body: closer2, StatusCode: 200, @@ -205,7 +205,7 @@ func testResponseGates5() merge.ResponseGates { b3 := []byte(`{"status":"success","data":[{"__name__":"test1","instance":"i2","job":"trickster"}]}`) closer3 := io.NopCloser(bytes.NewReader(b3)) - rsc3 := request.NewResources(nil, nil, nil, nil, nil, nil, nil) + rsc3 := request.NewResources(nil, nil, nil, nil, nil, nil, testLogger) rsc3.Response = &http.Response{ Body: closer3, StatusCode: 200, @@ -225,7 +225,7 @@ func testResponseGates6() merge.ResponseGates { b1 := []byte(`{"status":"error"`) closer1 := io.NopCloser(bytes.NewReader(b1)) - rsc1 := request.NewResources(nil, nil, nil, nil, nil, nil, nil) + rsc1 := request.NewResources(nil, nil, nil, nil, nil, nil, testLogger) rsc1.Response = &http.Response{ Body: closer1, StatusCode: 400, @@ -239,7 +239,7 @@ func testResponseGates6() merge.ResponseGates { b2 := []byte(`{"status":"error","data":[{"__name__":"should","instance":"not","job":"append"}]}`) closer2 := io.NopCloser(bytes.NewReader(b1)) - rsc2 := request.NewResources(nil, nil, nil, nil, nil, nil, nil) + rsc2 := request.NewResources(nil, nil, nil, nil, nil, nil, testLogger) rsc2.Response = &http.Response{ Body: closer2, StatusCode: 400, diff --git a/pkg/backends/prometheus/model/vector.go b/pkg/backends/prometheus/model/vector.go index 8f0d30dcf..6a794e35b 100644 --- a/pkg/backends/prometheus/model/vector.go +++ b/pkg/backends/prometheus/model/vector.go @@ -65,7 +65,7 @@ func MergeAndWriteVector(w http.ResponseWriter, r *http.Request, rgs merge.Respo t2, err := UnmarshalTimeseries(rg.Body(), trq) if err != nil { - logging.Error(rg.Resources.Logger, "vector unmarshaling error", + rg.Resources.Logger.Error("vector unmarshaling error", logging.Pairs{"provider": "prometheus", "detail": err.Error()}) continue } @@ -73,8 +73,8 @@ func MergeAndWriteVector(w http.ResponseWriter, r *http.Request, rgs merge.Respo if ts == nil { ds, ok := t2.(*dataset.DataSet) if !ok { - logging.Error(rg.Resources.Logger, "vector unmarshaling error", - logging.Pairs{"provider": "prometheus", "detail": err.Error()}) + rg.Resources.Logger.Error("vector unmarshaling error", + logging.Pairs{"provider": "prometheus"}) continue } ts = ds diff --git a/pkg/backends/prometheus/model/vector_test.go b/pkg/backends/prometheus/model/vector_test.go index ce2e7f9a5..828796842 100644 --- a/pkg/backends/prometheus/model/vector_test.go +++ b/pkg/backends/prometheus/model/vector_test.go @@ -63,7 +63,7 @@ func testResponseGates7() merge.ResponseGates { b1 := []byte(testVector) closer1 := io.NopCloser(bytes.NewReader(b1)) - rsc1 := request.NewResources(nil, nil, nil, nil, nil, nil, nil) + rsc1 := request.NewResources(nil, nil, nil, nil, nil, nil, testLogger) rsc1.Response = &http.Response{ Body: closer1, StatusCode: 200, @@ -78,7 +78,7 @@ func testResponseGates7() merge.ResponseGates { b2bad := []byte(`{"stat`) closer2 := io.NopCloser(bytes.NewReader(b2bad)) - rsc2 := request.NewResources(nil, nil, nil, nil, nil, nil, nil) + rsc2 := request.NewResources(nil, nil, nil, nil, nil, nil, testLogger) rsc2.Response = &http.Response{ Body: closer2, StatusCode: 200, @@ -92,7 +92,7 @@ func testResponseGates7() merge.ResponseGates { b3 := []byte(testVector2) closer3 := io.NopCloser(bytes.NewReader(b3)) - rsc3 := request.NewResources(nil, nil, nil, nil, nil, nil, nil) + rsc3 := request.NewResources(nil, nil, nil, nil, nil, nil, testLogger) rsc3.Response = &http.Response{ Body: closer3, StatusCode: 200, @@ -114,7 +114,7 @@ func testResponseGates8() merge.ResponseGates { b1 := []byte(`{"status":"error","data":{}`) closer1 := io.NopCloser(bytes.NewReader(b1)) - rsc1 := request.NewResources(nil, nil, nil, nil, nil, nil, nil) + rsc1 := request.NewResources(nil, nil, nil, nil, nil, nil, testLogger) rsc1.Response = &http.Response{ Body: closer1, StatusCode: 400, @@ -128,7 +128,7 @@ func testResponseGates8() merge.ResponseGates { b2 := []byte(`{"status":"error","data":{}`) closer2 := io.NopCloser(bytes.NewReader(b1)) - rsc2 := request.NewResources(nil, nil, nil, nil, nil, nil, nil) + rsc2 := request.NewResources(nil, nil, nil, nil, nil, nil, testLogger) rsc2.Response = &http.Response{ Body: closer2, StatusCode: 400, diff --git a/pkg/backends/prometheus/prometheus_test.go b/pkg/backends/prometheus/prometheus_test.go index b11b11067..fd16dbad8 100644 --- a/pkg/backends/prometheus/prometheus_test.go +++ b/pkg/backends/prometheus/prometheus_test.go @@ -27,18 +27,15 @@ import ( "github.com/trickstercache/trickster/v2/pkg/backends" bo "github.com/trickstercache/trickster/v2/pkg/backends/options" - "github.com/trickstercache/trickster/v2/pkg/backends/prometheus/model" po "github.com/trickstercache/trickster/v2/pkg/backends/prometheus/options" cr "github.com/trickstercache/trickster/v2/pkg/cache/registration" "github.com/trickstercache/trickster/v2/pkg/config" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" pe "github.com/trickstercache/trickster/v2/pkg/proxy/errors" "github.com/trickstercache/trickster/v2/pkg/proxy/request" "github.com/trickstercache/trickster/v2/pkg/timeseries" ) -var testModeler = model.NewModeler() - func TestPrometheusClientInterfacing(t *testing.T) { // this test ensures the client will properly conform to the @@ -67,7 +64,7 @@ func TestNewClient(t *testing.T) { t.Fatalf("Could not load configuration: %s", err.Error()) } - caches := cr.LoadCachesFromConfig(conf, tl.ConsoleLogger("error")) + caches := cr.LoadCachesFromConfig(conf, logging.ConsoleLogger("error")) defer cr.CloseCaches(caches) cache, ok := caches["default"] if !ok { @@ -143,7 +140,7 @@ func TestParseTimeRangeQuery(t *testing.T) { req := &http.Request{URL: u} o := bo.New() o.Prometheus = &po.Options{Labels: map[string]string{"test": "trickster"}} - rsc := request.NewResources(o, nil, nil, nil, nil, nil, nil) + rsc := request.NewResources(o, nil, nil, nil, nil, nil, testLogger) req = request.SetResources(req, rsc) client := &Client{} @@ -378,7 +375,7 @@ func TestParseVectorQuery(t *testing.T) { o := bo.New() o.Prometheus = &po.Options{Labels: map[string]string{"test": "trickster"}} - rsc := request.NewResources(o, nil, nil, nil, nil, nil, nil) + rsc := request.NewResources(o, nil, nil, nil, nil, nil, testLogger) req = request.SetResources(req, rsc) rounder := time.Second * 15 diff --git a/pkg/backends/prometheus/transformations.go b/pkg/backends/prometheus/transformations.go index 6a69363f3..16d6f7376 100644 --- a/pkg/backends/prometheus/transformations.go +++ b/pkg/backends/prometheus/transformations.go @@ -48,7 +48,7 @@ func (c *Client) processVectorTransformations(w http.ResponseWriter, rg *merge.R headers.Merge(h, rg.Header()) t2, err := model.UnmarshalTimeseries(bytes, trq) if err != nil || t2 == nil { - logging.Error(rg.Resources.Logger, "vector unmarshaling error", + rg.Resources.Logger.Error("vector unmarshaling error", logging.Pairs{"provider": "prometheus", "detail": err.Error()}) defaultWrite(rg.Response.StatusCode, w, bytes) return diff --git a/pkg/backends/prometheus/transformations_test.go b/pkg/backends/prometheus/transformations_test.go index 943428778..292776bdf 100644 --- a/pkg/backends/prometheus/transformations_test.go +++ b/pkg/backends/prometheus/transformations_test.go @@ -21,11 +21,14 @@ import ( "net/http/httptest" "testing" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" "github.com/trickstercache/trickster/v2/pkg/proxy/request" "github.com/trickstercache/trickster/v2/pkg/proxy/response/merge" "github.com/trickstercache/trickster/v2/pkg/timeseries/dataset" ) +var testLogger = logging.NoopLogger() + func TestProcessTransformations(t *testing.T) { // passing test case is no panics c := &Client{injectLabels: map[string]string{"test": "trickster"}} @@ -50,7 +53,7 @@ func TestProcessVectorTransformations(t *testing.T) { r, _ := http.NewRequest(http.MethodGet, "http://example.com/", nil) resp := &http.Response{StatusCode: 200} - rsc := &request.Resources{} + rsc := &request.Resources{Logger: testLogger} rg := merge.NewResponseGate(w, r, rsc) rg.Response = resp rg.Write([]byte("trickster")) diff --git a/pkg/backends/prometheus/url_test.go b/pkg/backends/prometheus/url_test.go index 6e9d935f5..e4a575888 100644 --- a/pkg/backends/prometheus/url_test.go +++ b/pkg/backends/prometheus/url_test.go @@ -73,8 +73,7 @@ func TestSetExtent(t *testing.T) { pc.SetExtent(r, nil, e) if int(r.ContentLength) != len(expected) { b, _ := io.ReadAll(r.Body) - fmt.Println(string(b)) - t.Errorf("expected %d got %d", len(expected), r.ContentLength) + t.Errorf("expected %d got %d / %d", len(expected), r.ContentLength, len(b)) } } diff --git a/pkg/cache/badger/badger.go b/pkg/cache/badger/badger.go index 3b948c3b3..832346200 100644 --- a/pkg/cache/badger/badger.go +++ b/pkg/cache/badger/badger.go @@ -25,7 +25,7 @@ import ( "github.com/trickstercache/trickster/v2/pkg/cache/options" "github.com/trickstercache/trickster/v2/pkg/cache/status" "github.com/trickstercache/trickster/v2/pkg/locks" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" "github.com/dgraph-io/badger" ) @@ -34,7 +34,7 @@ import ( type Cache struct { Name string Config *options.Options - Logger interface{} + Logger logging.Logger locker locks.NamedLocker dbh *badger.DB @@ -57,7 +57,7 @@ func (c *Cache) Configuration() *options.Options { // Connect opens the configured Badger key-value store func (c *Cache) Connect() error { - tl.Info(c.Logger, "badger cache setup", tl.Pairs{"cacheDir": c.Config.Badger.Directory}) + c.Logger.Info("badger cache setup", logging.Pairs{"cacheDir": c.Config.Badger.Directory}) opts := badger.DefaultOptions(c.Config.Badger.Directory) opts.ValueDir = c.Config.Badger.ValueDirectory @@ -74,7 +74,7 @@ func (c *Cache) Connect() error { // Store places the the data into the Badger Cache using the provided Key and TTL func (c *Cache) Store(cacheKey string, data []byte, ttl time.Duration) error { metrics.ObserveCacheOperation(c.Name, c.Config.Provider, "set", "none", float64(len(data))) - tl.Debug(c.Logger, "badger cache store", tl.Pairs{"key": cacheKey, "ttl": ttl}) + c.Logger.Debug("badger cache store", logging.Pairs{"key": cacheKey, "ttl": ttl}) return c.dbh.Update(func(txn *badger.Txn) error { return txn.SetEntry(&badger.Entry{Key: []byte(cacheKey), Value: data, ExpiresAt: uint64(time.Now().Add(ttl).Unix())}) }) @@ -95,26 +95,26 @@ func (c *Cache) Retrieve(cacheKey string, allowExpired bool) ([]byte, status.Loo }) if err == nil { - tl.Debug(c.Logger, "badger cache retrieve", tl.Pairs{"key": cacheKey}) + c.Logger.Debug("badger cache retrieve", logging.Pairs{"key": cacheKey}) metrics.ObserveCacheOperation(c.Name, c.Config.Provider, "get", "hit", float64(len(data))) return data, status.LookupStatusHit, nil } if err == badger.ErrKeyNotFound { err = cache.ErrKNF - tl.Debug(c.Logger, "badger cache miss", tl.Pairs{"key": cacheKey}) + c.Logger.Debug("badger cache miss", logging.Pairs{"key": cacheKey}) metrics.ObserveCacheMiss(cacheKey, c.Name, c.Config.Provider) return nil, status.LookupStatusKeyMiss, err } - tl.Debug(c.Logger, "badger cache retrieve failed", tl.Pairs{"key": cacheKey, "reason": err.Error()}) + c.Logger.Debug("badger cache retrieve failed", logging.Pairs{"key": cacheKey, "reason": err.Error()}) metrics.ObserveCacheMiss(cacheKey, c.Name, c.Config.Provider) return data, status.LookupStatusError, err } // Remove removes an object in cache, if present func (c *Cache) Remove(cacheKey string) { - tl.Debug(c.Logger, "badger cache remove", tl.Pairs{"key": cacheKey}) + c.Logger.Debug("badger cache remove", logging.Pairs{"key": cacheKey}) c.dbh.Update(func(txn *badger.Txn) error { return txn.Delete([]byte(cacheKey)) }) @@ -123,7 +123,7 @@ func (c *Cache) Remove(cacheKey string) { // BulkRemove removes a list of objects from the cache. noLock is not used for Badger func (c *Cache) BulkRemove(cacheKeys []string) { - tl.Debug(c.Logger, "badger cache bulk remove", tl.Pairs{}) + c.Logger.Debug("badger cache bulk remove", nil) c.dbh.Update(func(txn *badger.Txn) error { for _, key := range cacheKeys { @@ -152,7 +152,7 @@ func (c *Cache) SetTTL(cacheKey string, ttl time.Duration) { data, _ = item.ValueCopy(nil) return txn.SetEntry(&badger.Entry{Key: []byte(cacheKey), Value: data, ExpiresAt: uint64(time.Now().Add(ttl).Unix())}) }) - tl.Debug(c.Logger, "badger cache update-ttl", tl.Pairs{"key": cacheKey, "ttl": ttl, "success": err == nil}) + c.Logger.Debug("badger cache update-ttl", logging.Pairs{"key": cacheKey, "ttl": ttl, "success": err == nil}) if err == nil { metrics.ObserveCacheOperation(c.Name, c.Config.Provider, "update-ttl", "none", 0) } diff --git a/pkg/cache/badger/badger_test.go b/pkg/cache/badger/badger_test.go index e9fd30f73..e8ce4e4eb 100644 --- a/pkg/cache/badger/badger_test.go +++ b/pkg/cache/badger/badger_test.go @@ -24,7 +24,7 @@ import ( co "github.com/trickstercache/trickster/v2/pkg/cache/options" "github.com/trickstercache/trickster/v2/pkg/cache/status" "github.com/trickstercache/trickster/v2/pkg/locks" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" ) const provider = "badger" @@ -38,7 +38,7 @@ func newCacheConfig(dbPath string) *co.Options { func TestConfiguration(t *testing.T) { testDbPath := t.TempDir() + "/test.db" cacheConfig := newCacheConfig(testDbPath) - bc := Cache{Config: cacheConfig, Logger: tl.ConsoleLogger("error")} + bc := Cache{Config: cacheConfig, Logger: logging.ConsoleLogger("error")} cfg := bc.Configuration() if cfg.Provider != provider { @@ -49,7 +49,7 @@ func TestConfiguration(t *testing.T) { func TestBadgerCache_Connect(t *testing.T) { testDbPath := t.TempDir() + "/test.db" cacheConfig := newCacheConfig(testDbPath) - bc := Cache{Config: cacheConfig, Logger: tl.ConsoleLogger("error")} + bc := Cache{Config: cacheConfig, Logger: logging.ConsoleLogger("error")} // it should connect if err := bc.Connect(); err != nil { @@ -60,7 +60,7 @@ func TestBadgerCache_Connect(t *testing.T) { func TestBadgerCache_ConnectFailed(t *testing.T) { cacheConfig := newCacheConfig("/root/trickster-test-noaccess") - bc := Cache{Config: cacheConfig, Logger: tl.ConsoleLogger("error")} + bc := Cache{Config: cacheConfig, Logger: logging.ConsoleLogger("error")} // it should connect err := bc.Connect() @@ -73,7 +73,7 @@ func TestBadgerCache_ConnectFailed(t *testing.T) { func TestBadgerCache_Store(t *testing.T) { testDbPath := t.TempDir() + "/test.db" cacheConfig := newCacheConfig(testDbPath) - bc := Cache{Config: cacheConfig, Logger: tl.ConsoleLogger("error")} + bc := Cache{Config: cacheConfig, Logger: logging.ConsoleLogger("error")} if err := bc.Connect(); err != nil { t.Error(err) @@ -90,7 +90,7 @@ func TestBadgerCache_Store(t *testing.T) { func TestBadgerCache_Remove(t *testing.T) { testDbPath := t.TempDir() + "/test.db" cacheConfig := newCacheConfig(testDbPath) - bc := Cache{Config: cacheConfig, Logger: tl.ConsoleLogger("error")} + bc := Cache{Config: cacheConfig, Logger: logging.ConsoleLogger("error")} if err := bc.Connect(); err != nil { t.Error(err) @@ -130,7 +130,7 @@ func TestBadgerCache_Remove(t *testing.T) { func TestBadgerCache_BulkRemove(t *testing.T) { testDbPath := t.TempDir() + "/test.db" cacheConfig := newCacheConfig(testDbPath) - bc := Cache{Config: cacheConfig, Logger: tl.ConsoleLogger("error")} + bc := Cache{Config: cacheConfig, Logger: logging.ConsoleLogger("error")} if err := bc.Connect(); err != nil { t.Error(err) @@ -173,7 +173,7 @@ func TestBadgerCache_BulkRemove(t *testing.T) { func TestBadgerCache_Retrieve(t *testing.T) { testDbPath := t.TempDir() + "/test.db" cacheConfig := newCacheConfig(testDbPath) - bc := Cache{Config: cacheConfig, Logger: tl.ConsoleLogger("error")} + bc := Cache{Config: cacheConfig, Logger: logging.ConsoleLogger("error")} if err := bc.Connect(); err != nil { t.Error(err) @@ -252,7 +252,7 @@ func TestBadgerCache_Close(t *testing.T) { testDbPath := t.TempDir() + "/test.db" cacheConfig := &co.Options{Provider: provider, Badger: &bo.Options{Directory: testDbPath, ValueDirectory: testDbPath}} - bc := Cache{Config: cacheConfig, Logger: tl.ConsoleLogger("error")} + bc := Cache{Config: cacheConfig, Logger: logging.ConsoleLogger("error")} if err := bc.Connect(); err != nil { t.Error(err) diff --git a/pkg/cache/bbolt/bbolt.go b/pkg/cache/bbolt/bbolt.go index 21954431f..d007e936f 100644 --- a/pkg/cache/bbolt/bbolt.go +++ b/pkg/cache/bbolt/bbolt.go @@ -28,7 +28,7 @@ import ( "github.com/trickstercache/trickster/v2/pkg/cache/options" "github.com/trickstercache/trickster/v2/pkg/cache/status" "github.com/trickstercache/trickster/v2/pkg/locks" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" "go.etcd.io/bbolt" ) @@ -37,7 +37,7 @@ import ( type Cache struct { Name string Config *options.Options - Logger interface{} + Logger logging.Logger Index *index.Index locker locks.NamedLocker lockPrefix string @@ -81,7 +81,8 @@ func (c *Cache) Configuration() *options.Options { // Connect instantiates the Cache mutex map and starts the Expired Entry Reaper goroutine func (c *Cache) Connect() error { - tl.Info(c.Logger, "bbolt cache setup", tl.Pairs{"name": c.Name, "cacheFile": c.Config.BBolt.Filename}) + c.Logger.Info("bbolt cache setup", + logging.Pairs{"name": c.Name, "cacheFile": c.Config.BBolt.Filename}) c.lockPrefix = c.Name + ".bbolt." @@ -117,8 +118,8 @@ func (c *Cache) Store(cacheKey string, data []byte, ttl time.Duration) error { func (c *Cache) storeNoIndex(cacheKey string, data []byte) { err := c.store(cacheKey, data, 31536000*time.Second, false) if err != nil { - tl.Error(c.Logger, "cache failed to write non-indexed object", - tl.Pairs{"cacheName": c.Name, "cacheProvider": "bbolt", + c.Logger.Error("cache failed to write non-indexed object", + logging.Pairs{"cacheName": c.Name, "cacheProvider": "bbolt", "cacheKey": cacheKey, "objectSize": len(data)}) } } @@ -139,7 +140,8 @@ func (c *Cache) store(cacheKey string, data []byte, ttl time.Duration, updateInd if err != nil { return err } - tl.Debug(c.Logger, "bbolt cache store", tl.Pairs{"key": cacheKey, "ttl": ttl, "indexed": updateIndex}) + c.Logger.Debug("bbolt cache store", + logging.Pairs{"key": cacheKey, "ttl": ttl, "indexed": updateIndex}) if updateIndex { c.Index.UpdateObject(o) } @@ -169,7 +171,7 @@ func (c *Cache) retrieve(cacheKey string, allowExpired bool, b := tx.Bucket([]byte(c.Config.BBolt.Bucket)) data = b.Get([]byte(cacheKey)) if data == nil { - tl.Debug(c.Logger, "bbolt cache miss", tl.Pairs{"key": cacheKey}) + c.Logger.Debug("bbolt cache miss", logging.Pairs{"key": cacheKey}) metrics.ObserveCacheMiss(cacheKey, c.Name, c.Config.Provider) return cache.ErrKNF } @@ -196,7 +198,7 @@ func (c *Cache) retrieve(cacheKey string, allowExpired bool, o.Expiration = c.Index.GetExpiration(cacheKey) if allowExpired || o.Expiration.IsZero() || o.Expiration.After(time.Now()) { - tl.Debug(c.Logger, "bbolt cache retrieve", tl.Pairs{"cacheKey": cacheKey}) + c.Logger.Debug("bbolt cache retrieve", logging.Pairs{"cacheKey": cacheKey}) if atime { go c.Index.UpdateObjectAccessTime(cacheKey) } @@ -227,15 +229,15 @@ func (c *Cache) remove(cacheKey string, isBulk bool) error { }) nl.Release() if err != nil { - tl.Error(c.Logger, "bbolt cache key delete failure", - tl.Pairs{"cacheKey": cacheKey, "reason": err.Error()}) + c.Logger.Error("bbolt cache key delete failure", + logging.Pairs{"cacheKey": cacheKey, "reason": err.Error()}) return err } if !isBulk { go c.Index.RemoveObject(cacheKey) } metrics.ObserveCacheDel(c.Name, c.Config.Provider, 0) - tl.Debug(c.Logger, "bbolt cache key delete", tl.Pairs{"key": cacheKey}) + c.Logger.Debug("bbolt cache key delete", logging.Pairs{"key": cacheKey}) return nil } diff --git a/pkg/cache/bbolt/bbolt_test.go b/pkg/cache/bbolt/bbolt_test.go index 74e592038..bc9d77b97 100644 --- a/pkg/cache/bbolt/bbolt_test.go +++ b/pkg/cache/bbolt/bbolt_test.go @@ -28,7 +28,7 @@ import ( co "github.com/trickstercache/trickster/v2/pkg/cache/options" "github.com/trickstercache/trickster/v2/pkg/cache/status" "github.com/trickstercache/trickster/v2/pkg/locks" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" ) const cacheProvider = "bbolt" @@ -46,7 +46,7 @@ func storeBenchmark(b *testing.B) Cache { BBolt: &bo.Options{Filename: testDbPath, Bucket: "trickster_test"}, Index: &io.Options{ReapInterval: time.Second}, } - bc := Cache{Config: &cacheConfig, Logger: tl.ConsoleLogger("error"), locker: locks.NewNamedLocker()} + bc := Cache{Config: &cacheConfig, Logger: logging.ConsoleLogger("error"), locker: locks.NewNamedLocker()} err := bc.Connect() if err != nil { @@ -66,7 +66,7 @@ func storeBenchmark(b *testing.B) Cache { func TestConfiguration(t *testing.T) { testDbPath := t.TempDir() + "/test.db" cacheConfig := newCacheConfig(testDbPath) - bc := Cache{Config: &cacheConfig, Logger: tl.ConsoleLogger("error"), locker: locks.NewNamedLocker()} + bc := Cache{Config: &cacheConfig, Logger: logging.ConsoleLogger("error"), locker: locks.NewNamedLocker()} cfg := bc.Configuration() if cfg.Provider != cacheProvider { t.Errorf("expected %s got %s", cacheProvider, cfg.Provider) @@ -76,7 +76,7 @@ func TestConfiguration(t *testing.T) { func TestBboltCache_Connect(t *testing.T) { testDbPath := t.TempDir() + "/test.db" cacheConfig := newCacheConfig(testDbPath) - bc := Cache{Config: &cacheConfig, Logger: tl.ConsoleLogger("error"), locker: locks.NewNamedLocker()} + bc := Cache{Config: &cacheConfig, Logger: logging.ConsoleLogger("error"), locker: locks.NewNamedLocker()} // it should connect err := bc.Connect() if err != nil { @@ -88,7 +88,7 @@ func TestBboltCache_Connect(t *testing.T) { func TestBboltCache_ConnectFailed(t *testing.T) { const expected = `open /root/noaccess.bbolt:` cacheConfig := newCacheConfig("/root/noaccess.bbolt") - bc := Cache{Config: &cacheConfig, Logger: tl.ConsoleLogger("error"), locker: locks.NewNamedLocker()} + bc := Cache{Config: &cacheConfig, Logger: logging.ConsoleLogger("error"), locker: locks.NewNamedLocker()} // it should connect err := bc.Connect() if err == nil { @@ -105,7 +105,7 @@ func TestBboltCache_ConnectBadBucketName(t *testing.T) { testDbPath := t.TempDir() + "/test.db" cacheConfig := newCacheConfig(testDbPath) cacheConfig.BBolt.Bucket = "" - bc := Cache{Config: &cacheConfig, Logger: tl.ConsoleLogger("error"), locker: locks.NewNamedLocker()} + bc := Cache{Config: &cacheConfig, Logger: logging.ConsoleLogger("error"), locker: locks.NewNamedLocker()} // it should connect err := bc.Connect() if err == nil { @@ -120,7 +120,7 @@ func TestBboltCache_Store(t *testing.T) { testDbPath := t.TempDir() + "/test.db" cacheConfig := newCacheConfig(testDbPath) - bc := Cache{Config: &cacheConfig, Logger: tl.ConsoleLogger("error"), locker: locks.NewNamedLocker()} + bc := Cache{Config: &cacheConfig, Logger: logging.ConsoleLogger("error"), locker: locks.NewNamedLocker()} err := bc.Connect() if err != nil { @@ -144,7 +144,7 @@ func TestBboltCache_SetTTL(t *testing.T) { testDbPath := t.TempDir() + "/test.db" cacheConfig := newCacheConfig(testDbPath) - bc := Cache{Config: &cacheConfig, Logger: tl.ConsoleLogger("error"), locker: locks.NewNamedLocker()} + bc := Cache{Config: &cacheConfig, Logger: logging.ConsoleLogger("error"), locker: locks.NewNamedLocker()} err := bc.Connect() if err != nil { @@ -224,7 +224,7 @@ func TestBboltCache_StoreNoIndex(t *testing.T) { testDbPath := t.TempDir() + "/test.db" cacheConfig := newCacheConfig(testDbPath) - bc := Cache{Config: &cacheConfig, Logger: tl.ConsoleLogger("error"), locker: locks.NewNamedLocker()} + bc := Cache{Config: &cacheConfig, Logger: logging.ConsoleLogger("error"), locker: locks.NewNamedLocker()} err := bc.Connect() if err != nil { @@ -310,7 +310,7 @@ func TestBboltCache_Remove(t *testing.T) { testDbPath := t.TempDir() + "/test.db" cacheConfig := newCacheConfig(testDbPath) - bc := Cache{Config: &cacheConfig, Logger: tl.ConsoleLogger("error"), locker: locks.NewNamedLocker()} + bc := Cache{Config: &cacheConfig, Logger: logging.ConsoleLogger("error"), locker: locks.NewNamedLocker()} err := bc.Connect() if err != nil { @@ -390,7 +390,7 @@ func TestBboltCache_BulkRemove(t *testing.T) { testDbPath := t.TempDir() + "/test.db" cacheConfig := newCacheConfig(testDbPath) - bc := Cache{Config: &cacheConfig, Logger: tl.ConsoleLogger("error"), locker: locks.NewNamedLocker()} + bc := Cache{Config: &cacheConfig, Logger: logging.ConsoleLogger("error"), locker: locks.NewNamedLocker()} err := bc.Connect() if err != nil { @@ -458,7 +458,7 @@ func TestBboltCache_Retrieve(t *testing.T) { testDbPath := t.TempDir() + "/test.db" cacheConfig := newCacheConfig(testDbPath) - bc := Cache{Config: &cacheConfig, Logger: tl.ConsoleLogger("error"), locker: locks.NewNamedLocker()} + bc := Cache{Config: &cacheConfig, Logger: logging.ConsoleLogger("error"), locker: locks.NewNamedLocker()} err := bc.Connect() if err != nil { @@ -610,7 +610,7 @@ func TestLocker(t *testing.T) { func TestClose(t *testing.T) { testDbPath := t.TempDir() + "/test.db" cacheConfig := newCacheConfig(testDbPath) - bc := Cache{Config: &cacheConfig, Logger: tl.ConsoleLogger("error"), locker: locks.NewNamedLocker()} + bc := Cache{Config: &cacheConfig, Logger: logging.ConsoleLogger("error"), locker: locks.NewNamedLocker()} bc.dbh = nil err := bc.Close() if err != nil { diff --git a/pkg/cache/filesystem/filesystem.go b/pkg/cache/filesystem/filesystem.go index 34f9ddff5..27d4997e8 100644 --- a/pkg/cache/filesystem/filesystem.go +++ b/pkg/cache/filesystem/filesystem.go @@ -31,7 +31,7 @@ import ( "github.com/trickstercache/trickster/v2/pkg/cache/options" "github.com/trickstercache/trickster/v2/pkg/cache/status" "github.com/trickstercache/trickster/v2/pkg/locks" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" ) // Cache describes a Filesystem Cache @@ -39,7 +39,7 @@ type Cache struct { Name string Config *options.Options Index *index.Index - Logger interface{} + Logger logging.Logger locker locks.NamedLocker lockPrefix string } @@ -61,7 +61,7 @@ func (c *Cache) Configuration() *options.Options { // Connect instantiates the Cache mutex map and starts the Expired Entry Reaper goroutine func (c *Cache) Connect() error { - tl.Info(c.Logger, "filesystem cache setup", tl.Pairs{"name": c.Name, + c.Logger.Info("filesystem cache setup", logging.Pairs{"name": c.Name, "cachePath": c.Config.Filesystem.CachePath}) if err := makeDirectory(c.Config.Filesystem.CachePath); err != nil { return err @@ -83,9 +83,9 @@ func (c *Cache) Store(cacheKey string, data []byte, ttl time.Duration) error { func (c *Cache) storeNoIndex(cacheKey string, data []byte) { err := c.store(cacheKey, data, 31536000*time.Second, false) if err != nil { - tl.Error(c.Logger, - "cache failed to write non-indexed object", tl.Pairs{"cacheName": c.Name, - "cacheProvider": "filesystem", "cacheKey": cacheKey, "objectSize": len(data)}) + c.Logger.Error("cache failed to write non-indexed object", + logging.Pairs{"cacheName": c.Name, "cacheProvider": "filesystem", + "cacheKey": cacheKey, "objectSize": len(data)}) } } @@ -111,8 +111,8 @@ func (c *Cache) store(cacheKey string, data []byte, ttl time.Duration, updateInd nl.Release() return err } - tl.Debug(c.Logger, "filesystem cache store", - tl.Pairs{"key": cacheKey, "dataFile": dataFile, "indexed": updateIndex}) + c.Logger.Debug("filesystem cache store", + logging.Pairs{"key": cacheKey, "dataFile": dataFile, "indexed": updateIndex}) if updateIndex { c.Index.UpdateObject(o) } @@ -134,7 +134,8 @@ func (c *Cache) retrieve(cacheKey string, allowExpired bool, atime bool) ([]byte nl.RRelease() if err != nil { - tl.Debug(c.Logger, "filesystem cache miss", tl.Pairs{"key": cacheKey, "dataFile": dataFile}) + c.Logger.Debug("filesystem cache miss", + logging.Pairs{"key": cacheKey, "dataFile": dataFile}) metrics.ObserveCacheMiss(cacheKey, c.Name, c.Config.Provider) return nil, status.LookupStatusKeyMiss, cache.ErrKNF } @@ -155,7 +156,8 @@ func (c *Cache) retrieve(cacheKey string, allowExpired bool, atime bool) ([]byte o.Expiration = c.Index.GetExpiration(cacheKey) if allowExpired || o.Expiration.IsZero() || o.Expiration.After(time.Now()) { - tl.Debug(c.Logger, "filesystem cache retrieve", tl.Pairs{"key": cacheKey, "dataFile": dataFile}) + c.Logger.Debug("filesystem cache retrieve", + logging.Pairs{"key": cacheKey, "dataFile": dataFile}) if atime { go c.Index.UpdateObjectAccessTime(cacheKey) } diff --git a/pkg/cache/filesystem/filesystem_test.go b/pkg/cache/filesystem/filesystem_test.go index 7db46b9c1..7925a940b 100644 --- a/pkg/cache/filesystem/filesystem_test.go +++ b/pkg/cache/filesystem/filesystem_test.go @@ -29,7 +29,7 @@ import ( co "github.com/trickstercache/trickster/v2/pkg/cache/options" "github.com/trickstercache/trickster/v2/pkg/cache/status" "github.com/trickstercache/trickster/v2/pkg/locks" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" ) const cacheProvider = "filesystem" @@ -39,7 +39,7 @@ func storeBenchmark(b *testing.B) Cache { dir := b.TempDir() + "/cache/" + cacheProvider cacheConfig := co.Options{Provider: cacheProvider, Filesystem: &flo.Options{CachePath: dir}, Index: &io.Options{ReapInterval: time.Second}} - fc := Cache{Config: &cacheConfig, Logger: tl.ConsoleLogger("error"), locker: locks.NewNamedLocker()} + fc := Cache{Config: &cacheConfig, Logger: logging.ConsoleLogger("error"), locker: locks.NewNamedLocker()} err := fc.Connect() if err != nil { @@ -66,7 +66,7 @@ func newCacheConfig(t *testing.T) co.Options { func TestConfiguration(t *testing.T) { cacheConfig := newCacheConfig(t) cacheConfig.Filesystem.CachePath = t.TempDir() + "/cache" - fc := Cache{Config: &cacheConfig, Logger: tl.ConsoleLogger("error"), locker: locks.NewNamedLocker()} + fc := Cache{Config: &cacheConfig, Logger: logging.ConsoleLogger("error"), locker: locks.NewNamedLocker()} cfg := fc.Configuration() if cfg.Provider != cacheProvider { t.Fatalf("expected %s got %s", cacheProvider, cfg.Provider) @@ -77,7 +77,7 @@ func TestFilesystemCache_Connect(t *testing.T) { cacheConfig := newCacheConfig(t) cacheConfig.Filesystem.CachePath = t.TempDir() + "/cache" - fc := Cache{Config: &cacheConfig, Logger: tl.ConsoleLogger("error"), locker: locks.NewNamedLocker()} + fc := Cache{Config: &cacheConfig, Logger: logging.ConsoleLogger("error"), locker: locks.NewNamedLocker()} // it should connect err := fc.Connect() @@ -90,7 +90,7 @@ func TestFilesystemCache_ConnectFailed(t *testing.T) { const expected = `[/root/noaccess.trickster.filesystem.cache] directory is not writeable by trickster:` cacheConfig := newCacheConfig(t) cacheConfig.Filesystem.CachePath = "/root/noaccess.trickster.filesystem.cache" - fc := Cache{Config: &cacheConfig, Logger: tl.ConsoleLogger("error"), locker: locks.NewNamedLocker()} + fc := Cache{Config: &cacheConfig, Logger: logging.ConsoleLogger("error"), locker: locks.NewNamedLocker()} // it should connect err := fc.Connect() if err == nil { @@ -109,7 +109,7 @@ func TestFilesystemCache_Store(t *testing.T) { cacheConfig := newCacheConfig(t) cacheConfig.Filesystem.CachePath = t.TempDir() + "/cache" - fc := Cache{Config: &cacheConfig, Logger: tl.ConsoleLogger("error"), locker: locks.NewNamedLocker()} + fc := Cache{Config: &cacheConfig, Logger: logging.ConsoleLogger("error"), locker: locks.NewNamedLocker()} err := fc.Connect() if err != nil { @@ -154,7 +154,7 @@ func TestFilesystemCache_StoreNoIndex(t *testing.T) { cacheConfig := newCacheConfig(t) cacheConfig.Filesystem.CachePath = t.TempDir() + "/cache" - fc := Cache{Config: &cacheConfig, Logger: tl.ConsoleLogger("error"), locker: locks.NewNamedLocker()} + fc := Cache{Config: &cacheConfig, Logger: logging.ConsoleLogger("error"), locker: locks.NewNamedLocker()} err := fc.Connect() if err != nil { @@ -239,7 +239,7 @@ func TestFilesystemCache_SetTTL(t *testing.T) { cacheConfig := newCacheConfig(t) cacheConfig.Filesystem.CachePath = t.TempDir() + "/cache" - fc := Cache{Config: &cacheConfig, Logger: tl.ConsoleLogger("error"), locker: locks.NewNamedLocker()} + fc := Cache{Config: &cacheConfig, Logger: logging.ConsoleLogger("error"), locker: locks.NewNamedLocker()} err := fc.Connect() if err != nil { @@ -321,7 +321,7 @@ func TestFilesystemCache_Retrieve(t *testing.T) { cacheConfig := newCacheConfig(t) cacheConfig.Filesystem.CachePath = t.TempDir() + "/cache" - fc := Cache{Config: &cacheConfig, Logger: tl.ConsoleLogger("error"), locker: locks.NewNamedLocker()} + fc := Cache{Config: &cacheConfig, Logger: logging.ConsoleLogger("error"), locker: locks.NewNamedLocker()} err := fc.Connect() if err != nil { @@ -466,7 +466,7 @@ func TestFilesystemCache_Remove(t *testing.T) { cacheConfig := newCacheConfig(t) cacheConfig.Filesystem.CachePath = t.TempDir() + "/cache" - fc := Cache{Config: &cacheConfig, Logger: tl.ConsoleLogger("error"), locker: locks.NewNamedLocker()} + fc := Cache{Config: &cacheConfig, Logger: logging.ConsoleLogger("error"), locker: locks.NewNamedLocker()} err := fc.Connect() if err != nil { @@ -547,7 +547,7 @@ func TestFilesystemCache_BulkRemove(t *testing.T) { cacheConfig := newCacheConfig(t) cacheConfig.Filesystem.CachePath = t.TempDir() + "/cache" - fc := Cache{Config: &cacheConfig, Logger: tl.ConsoleLogger("error"), locker: locks.NewNamedLocker()} + fc := Cache{Config: &cacheConfig, Logger: logging.ConsoleLogger("error"), locker: locks.NewNamedLocker()} err := fc.Connect() if err != nil { diff --git a/pkg/cache/index/index.go b/pkg/cache/index/index.go index 985ee31ca..874854fe4 100644 --- a/pkg/cache/index/index.go +++ b/pkg/cache/index/index.go @@ -26,7 +26,7 @@ import ( "github.com/trickstercache/trickster/v2/pkg/cache" "github.com/trickstercache/trickster/v2/pkg/cache/index/options" "github.com/trickstercache/trickster/v2/pkg/cache/metrics" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" gm "github.com/trickstercache/trickster/v2/pkg/observability/metrics" ) @@ -107,7 +107,7 @@ func ObjectFromBytes(data []byte) (*Object, error) { // NewIndex returns a new Index based on the provided inputs func NewIndex(cacheName, cacheProvider string, indexData []byte, o *options.Options, bulkRemoveFunc func([]string), flushFunc func(cacheKey string, data []byte), - logger interface{}) *Index { + logger logging.Logger) *Index { i := &Index{} if len(indexData) > 0 { @@ -126,16 +126,16 @@ func NewIndex(cacheName, cacheProvider string, indexData []byte, o *options.Opti if o.FlushInterval > 0 { go i.flusher(logger) } else { - tl.Warn(logger, "cache index flusher did not start", - tl.Pairs{"cacheName": i.name, "flushInterval": o.FlushInterval}) + logger.Warn("cache index flusher did not start", + logging.Pairs{"cacheName": i.name, "flushInterval": o.FlushInterval}) } } if o.ReapInterval > 0 { go i.reaper(logger) } else { - tl.Warn(logger, "cache reaper did not start", - tl.Pairs{"cacheName": i.name, "reapInterval": o.ReapInterval}) + logger.Warn("cache reaper did not start", + logging.Pairs{"cacheName": i.name, "reapInterval": o.ReapInterval}) } gm.CacheMaxObjects.WithLabelValues(cacheName, cacheProvider).Set(float64(o.MaxSizeObjects)) @@ -252,7 +252,7 @@ func (idx *Index) GetExpiration(cacheKey string) time.Time { } // flusher periodically calls the cache's index flush func that writes the cache index to disk -func (idx *Index) flusher(logger interface{}) { +func (idx *Index) flusher(logger logging.Logger) { var lastFlush time.Time for !idx.isClosing { time.Sleep(idx.options.FlushInterval) @@ -265,20 +265,20 @@ func (idx *Index) flusher(logger interface{}) { idx.flusherExited = true } -func (idx *Index) flushOnce(logger interface{}) { +func (idx *Index) flushOnce(logger logging.Logger) { idx.mtx.Lock() bytes, err := idx.MarshalMsg(nil) idx.mtx.Unlock() if err != nil { - tl.Warn(logger, "unable to serialize index for flushing", - tl.Pairs{"cacheName": idx.name, "detail": err.Error()}) + logger.Warn("unable to serialize index for flushing", + logging.Pairs{"cacheName": idx.name, "detail": err.Error()}) return } idx.flushFunc(IndexKey, bytes) } // reaper continually iterates through the cache to find expired elements and removes them -func (idx *Index) reaper(logger interface{}) { +func (idx *Index) reaper(logger logging.Logger) { for !idx.isClosing { idx.reap(logger) time.Sleep(idx.options.ReapInterval) @@ -290,7 +290,7 @@ type objectsAtime []*Object // reap makes a single iteration through the cache index to to find and remove expired elements // and evict least-recently-accessed elements to maintain the Maximum allowed Cache Size -func (idx *Index) reap(logger interface{}) { +func (idx *Index) reap(logger logging.Logger) { idx.mtx.Lock() defer idx.mtx.Unlock() @@ -333,9 +333,9 @@ func (idx *Index) reap(logger interface{}) { return } - tl.Debug(logger, + logger.Debug( "max cache size reached. evicting least-recently-accessed records", - tl.Pairs{ + logging.Pairs{ "reason": evictionType, "cacheSizeBytes": idx.CacheSize, "maxSizeBytes": idx.options.MaxSizeBytes, "cacheSizeObjects": idx.ObjectCount, "maxSizeObjects": idx.options.MaxSizeObjects, @@ -380,8 +380,8 @@ func (idx *Index) reap(logger interface{}) { cacheChanged = true } - tl.Debug(logger, "size-based cache eviction exercise completed", - tl.Pairs{ + logger.Debug("size-based cache eviction exercise completed", + logging.Pairs{ "reason": evictionType, "cacheSizeBytes": idx.CacheSize, "maxSizeBytes": idx.options.MaxSizeBytes, "cacheSizeObjects": idx.ObjectCount, "maxSizeObjects": idx.options.MaxSizeObjects, diff --git a/pkg/cache/index/index_test.go b/pkg/cache/index/index_test.go index e5720361b..becf74850 100644 --- a/pkg/cache/index/index_test.go +++ b/pkg/cache/index/index_test.go @@ -23,10 +23,10 @@ import ( io "github.com/trickstercache/trickster/v2/pkg/cache/index/options" co "github.com/trickstercache/trickster/v2/pkg/cache/options" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" ) -var testLogger = tl.ConsoleLogger("error") +var testLogger = logging.ConsoleLogger("error") var testBulkIndex *Index diff --git a/pkg/cache/memory/memory.go b/pkg/cache/memory/memory.go index 9093b3091..57bd62d49 100644 --- a/pkg/cache/memory/memory.go +++ b/pkg/cache/memory/memory.go @@ -28,7 +28,7 @@ import ( "github.com/trickstercache/trickster/v2/pkg/cache/options" "github.com/trickstercache/trickster/v2/pkg/cache/status" "github.com/trickstercache/trickster/v2/pkg/locks" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" ) // Cache defines a a Memory Cache client that conforms to the Cache interface @@ -37,7 +37,7 @@ type Cache struct { client sync.Map Config *options.Options Index *index.Index - Logger interface{} + Logger logging.Logger locker locks.NamedLocker lockPrefix string } @@ -71,7 +71,7 @@ func (c *Cache) Configuration() *options.Options { // Connect initializes the Cache func (c *Cache) Connect() error { - tl.Info(c.Logger, "memorycache setup", tl.Pairs{"name": c.Name, + c.Logger.Info("memorycache setup", logging.Pairs{"name": c.Name, "maxSizeBytes": c.Config.Index.MaxSizeBytes, "maxSizeObjects": c.Config.Index.MaxSizeObjects}) c.lockPrefix = c.Name + ".memory." c.client = sync.Map{} @@ -113,8 +113,8 @@ func (c *Cache) store(cacheKey string, byteData []byte, refData cache.ReferenceO if o1 != nil && o2 != nil { nl, _ := c.locker.Acquire(c.lockPrefix + cacheKey) - tl.Debug(c.Logger, "memorycache cache store", - tl.Pairs{"cacheName": c.Name, "cacheKey": cacheKey, "length": l, "ttl": ttl, "is_direct": isDirect}) + c.Logger.Debug("memorycache cache store", + logging.Pairs{"cacheName": c.Name, "cacheKey": cacheKey, "length": l, "ttl": ttl, "is_direct": isDirect}) c.client.Store(cacheKey, o1) if updateIndex { c.Index.UpdateObject(o2) @@ -162,7 +162,7 @@ func (c *Cache) retrieve(cacheKey string, allowExpired bool, atime bool) (*index o.Expiration = c.Index.GetExpiration(cacheKey) if allowExpired || o.Expiration.IsZero() || o.Expiration.After(time.Now()) { - tl.Debug(c.Logger, "memory cache retrieve", tl.Pairs{"cacheKey": cacheKey}) + c.Logger.Debug("memory cache retrieve", logging.Pairs{"cacheKey": cacheKey}) if atime { go c.Index.UpdateObjectAccessTime(cacheKey) } diff --git a/pkg/cache/memory/memory_test.go b/pkg/cache/memory/memory_test.go index 9c9f0fb33..168770d10 100644 --- a/pkg/cache/memory/memory_test.go +++ b/pkg/cache/memory/memory_test.go @@ -26,7 +26,7 @@ import ( co "github.com/trickstercache/trickster/v2/pkg/cache/options" "github.com/trickstercache/trickster/v2/pkg/cache/status" "github.com/trickstercache/trickster/v2/pkg/locks" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" ) const provider = "memory" @@ -43,7 +43,7 @@ func (r *testReferenceObject) Size() int { func storeBenchmark(b *testing.B) *Cache { cacheConfig := co.Options{Provider: provider, Index: &io.Options{ReapInterval: 0}} - mc := &Cache{Config: &cacheConfig, Logger: tl.ConsoleLogger("error"), locker: testLocker} + mc := &Cache{Config: &cacheConfig, Logger: logging.ConsoleLogger("error"), locker: testLocker} err := mc.Connect() if err != nil { @@ -65,7 +65,7 @@ func newCacheConfig(t *testing.T) co.Options { func TestConfiguration(t *testing.T) { cacheConfig := newCacheConfig(t) - mc := Cache{Config: &cacheConfig, Logger: tl.ConsoleLogger("error")} + mc := Cache{Config: &cacheConfig, Logger: logging.ConsoleLogger("error")} cfg := mc.Configuration() if cfg.Provider != provider { t.Fatalf("expected %s got %s", provider, cfg.Provider) @@ -75,7 +75,7 @@ func TestConfiguration(t *testing.T) { func TestCache_Connect(t *testing.T) { cacheConfig := newCacheConfig(t) - mc := Cache{Config: &cacheConfig, Logger: tl.ConsoleLogger("error")} + mc := Cache{Config: &cacheConfig, Logger: logging.ConsoleLogger("error")} // it should connect err := mc.Connect() @@ -87,7 +87,7 @@ func TestCache_Connect(t *testing.T) { func TestCache_StoreReferenceDirect(t *testing.T) { cacheConfig := newCacheConfig(t) - mc := Cache{Config: &cacheConfig, Logger: tl.ConsoleLogger("error"), locker: testLocker} + mc := Cache{Config: &cacheConfig, Logger: logging.ConsoleLogger("error"), locker: testLocker} err := mc.Connect() if err != nil { @@ -110,7 +110,7 @@ func TestCache_StoreReferenceDirect(t *testing.T) { func TestCache_StoreReference(t *testing.T) { cacheConfig := newCacheConfig(t) - mc := Cache{Config: &cacheConfig, Logger: tl.ConsoleLogger("error"), locker: testLocker} + mc := Cache{Config: &cacheConfig, Logger: logging.ConsoleLogger("error"), locker: testLocker} err := mc.Connect() if err != nil { @@ -125,7 +125,7 @@ func TestCache_StoreReference(t *testing.T) { func TestCache_Store(t *testing.T) { cacheConfig := newCacheConfig(t) - mc := Cache{Config: &cacheConfig, Logger: tl.ConsoleLogger("error"), locker: testLocker} + mc := Cache{Config: &cacheConfig, Logger: logging.ConsoleLogger("error"), locker: testLocker} err := mc.Connect() if err != nil { @@ -145,7 +145,7 @@ func BenchmarkCache_Store(b *testing.B) { func TestCache_Retrieve(t *testing.T) { cacheConfig := newCacheConfig(t) - mc := Cache{Config: &cacheConfig, Logger: tl.ConsoleLogger("error"), locker: testLocker} + mc := Cache{Config: &cacheConfig, Logger: logging.ConsoleLogger("error"), locker: testLocker} err := mc.Connect() if err != nil { @@ -233,13 +233,13 @@ func BenchmarkCache_Retrieve(b *testing.B) { func TestCache_Close(t *testing.T) { cacheConfig := newCacheConfig(t) - mc := Cache{Config: &cacheConfig, Logger: tl.ConsoleLogger("error")} + mc := Cache{Config: &cacheConfig, Logger: logging.ConsoleLogger("error")} mc.Close() } func TestCache_Remove(t *testing.T) { cacheConfig := newCacheConfig(t) - mc := Cache{Config: &cacheConfig, Logger: tl.ConsoleLogger("error"), locker: testLocker} + mc := Cache{Config: &cacheConfig, Logger: logging.ConsoleLogger("error"), locker: testLocker} err := mc.Connect() if err != nil { @@ -317,7 +317,7 @@ func BenchmarkCache_Remove(b *testing.B) { func TestCache_BulkRemove(t *testing.T) { cacheConfig := newCacheConfig(t) - mc := Cache{Config: &cacheConfig, Logger: tl.ConsoleLogger("error"), locker: testLocker} + mc := Cache{Config: &cacheConfig, Logger: logging.ConsoleLogger("error"), locker: testLocker} err := mc.Connect() if err != nil { @@ -381,7 +381,7 @@ func BenchmarkCache_BulkRemove(b *testing.B) { func TestMemoryCache_SetTTL(t *testing.T) { cacheConfig := newCacheConfig(t) - mc := Cache{Config: &cacheConfig, Logger: tl.ConsoleLogger("error"), locker: testLocker} + mc := Cache{Config: &cacheConfig, Logger: logging.ConsoleLogger("error"), locker: testLocker} err := mc.Connect() if err != nil { diff --git a/pkg/cache/redis/redis.go b/pkg/cache/redis/redis.go index 993abc289..2188e7357 100644 --- a/pkg/cache/redis/redis.go +++ b/pkg/cache/redis/redis.go @@ -26,7 +26,7 @@ import ( "github.com/trickstercache/trickster/v2/pkg/cache/options" "github.com/trickstercache/trickster/v2/pkg/cache/status" "github.com/trickstercache/trickster/v2/pkg/locks" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" "github.com/go-redis/redis" ) @@ -38,7 +38,7 @@ const Redis = "redis" type Cache struct { Name string Config *options.Options - Logger interface{} + Logger logging.Logger locker locks.NamedLocker client redis.Cmdable @@ -62,8 +62,9 @@ func (c *Cache) Configuration() *options.Options { // Connect connects to the configured Redis endpoint func (c *Cache) Connect() error { - tl.Info(c.Logger, "connecting to redis", - tl.Pairs{"protocol": c.Config.Redis.Protocol, "Endpoint": c.Config.Redis.Endpoint}) + c.Logger.Info("connecting to redis", + logging.Pairs{"protocol": c.Config.Redis.Protocol, + "endpoint": c.Config.Redis.Endpoint}) switch c.Config.Redis.ClientType { case "sentinel": @@ -97,7 +98,7 @@ func (c *Cache) Connect() error { // Store places the the data into the Redis Cache using the provided Key and TTL func (c *Cache) Store(cacheKey string, data []byte, ttl time.Duration) error { metrics.ObserveCacheOperation(c.Name, c.Config.Provider, "set", "none", float64(len(data))) - tl.Debug(c.Logger, "redis cache store", tl.Pairs{"key": cacheKey}) + c.Logger.Debug("redis cache store", logging.Pairs{"key": cacheKey}) return c.client.Set(cacheKey, data, ttl).Err() } @@ -108,25 +109,25 @@ func (c *Cache) Retrieve(cacheKey string, allowExpired bool) ([]byte, status.Loo if err == nil { data := []byte(res) - tl.Debug(c.Logger, "redis cache retrieve", tl.Pairs{"key": cacheKey}) + c.Logger.Debug("redis cache retrieve", logging.Pairs{"key": cacheKey}) metrics.ObserveCacheOperation(c.Name, c.Config.Provider, "get", "hit", float64(len(data))) return data, status.LookupStatusHit, nil } if err == redis.Nil { - tl.Debug(c.Logger, "redis cache miss", tl.Pairs{"key": cacheKey}) + c.Logger.Debug("redis cache miss", logging.Pairs{"key": cacheKey}) metrics.ObserveCacheMiss(cacheKey, c.Name, c.Config.Provider) return nil, status.LookupStatusKeyMiss, cache.ErrKNF } - tl.Debug(c.Logger, "redis cache retrieve failed", tl.Pairs{"key": cacheKey, "reason": err.Error()}) + c.Logger.Debug("redis cache retrieve failed", logging.Pairs{"key": cacheKey, "reason": err.Error()}) metrics.ObserveCacheMiss(cacheKey, c.Name, c.Config.Provider) return nil, status.LookupStatusError, err } // Remove removes an object in cache, if present func (c *Cache) Remove(cacheKey string) { - tl.Debug(c.Logger, "redis cache remove", tl.Pairs{"key": cacheKey}) + c.Logger.Debug("redis cache remove", logging.Pairs{"key": cacheKey}) c.client.Del(cacheKey) metrics.ObserveCacheDel(c.Name, c.Config.Provider, 0) } @@ -138,14 +139,14 @@ func (c *Cache) SetTTL(cacheKey string, ttl time.Duration) { // BulkRemove removes a list of objects from the cache. noLock is not used for Redis func (c *Cache) BulkRemove(cacheKeys []string) { - tl.Debug(c.Logger, "redis cache bulk remove", tl.Pairs{}) + c.Logger.Debug("redis cache bulk remove", nil) c.client.Del(cacheKeys...) metrics.ObserveCacheDel(c.Name, c.Config.Provider, float64(len(cacheKeys))) } // Close disconnects from the Redis Cache func (c *Cache) Close() error { - tl.Info(c.Logger, "closing redis connection", tl.Pairs{}) + c.Logger.Info("closing redis connection", nil) return c.closer() } diff --git a/pkg/cache/redis/redis_test.go b/pkg/cache/redis/redis_test.go index 57cbbf265..6ede09389 100644 --- a/pkg/cache/redis/redis_test.go +++ b/pkg/cache/redis/redis_test.go @@ -26,7 +26,7 @@ import ( "github.com/trickstercache/trickster/v2/pkg/cache/status" "github.com/trickstercache/trickster/v2/pkg/config" "github.com/trickstercache/trickster/v2/pkg/locks" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" "github.com/alicebob/miniredis" ) @@ -68,7 +68,7 @@ func setupRedisCache(ct clientType) (*Cache, func()) { cacheConfig := &co.Options{Provider: "redis", Redis: rcfg} conf.Caches = map[string]*co.Options{"default": cacheConfig} - return &Cache{Config: cacheConfig, Logger: tl.ConsoleLogger("error")}, close + return &Cache{Config: cacheConfig, Logger: logging.ConsoleLogger("error")}, close } func TestClientSelectionSentinel(t *testing.T) { @@ -84,7 +84,7 @@ func TestClientSelectionSentinel(t *testing.T) { if !ok { t.Errorf("expected cache named %s", cacheName) } - cache := Cache{Name: cacheName, Config: cfg, Logger: tl.ConsoleLogger("error")} + cache := Cache{Name: cacheName, Config: cfg, Logger: logging.ConsoleLogger("error")} if err != nil { t.Error(err) } @@ -162,7 +162,7 @@ func TestClientSelectionCluster(t *testing.T) { if !ok { t.Errorf("expected cache named %s", cacheName) } - cache := Cache{Name: cacheName, Config: cfg, Logger: tl.ConsoleLogger("error")} + cache := Cache{Name: cacheName, Config: cfg, Logger: logging.ConsoleLogger("error")} if err != nil { t.Error(err) } @@ -185,7 +185,7 @@ func TestClientSelectionStandard(t *testing.T) { if !ok { t.Errorf("expected cache named %s", cacheName) } - cache := Cache{Name: cacheName, Config: cfg, Logger: tl.ConsoleLogger("error")} + cache := Cache{Name: cacheName, Config: cfg, Logger: logging.ConsoleLogger("error")} if err != nil { t.Error(err) } diff --git a/pkg/cache/registration/registration.go b/pkg/cache/registration/registration.go index 4e8bd7f09..752b96015 100644 --- a/pkg/cache/registration/registration.go +++ b/pkg/cache/registration/registration.go @@ -28,6 +28,7 @@ import ( "github.com/trickstercache/trickster/v2/pkg/cache/redis" "github.com/trickstercache/trickster/v2/pkg/config" "github.com/trickstercache/trickster/v2/pkg/locks" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" ) // Cache Interface Types @@ -50,7 +51,7 @@ const ( // } // LoadCachesFromConfig iterates the Caching Config and Connects/Maps each Cache -func LoadCachesFromConfig(conf *config.Config, logger interface{}) map[string]cache.Cache { +func LoadCachesFromConfig(conf *config.Config, logger logging.Logger) map[string]cache.Cache { caches := make(map[string]cache.Cache) for k, v := range conf.Caches { c := NewCache(k, v, logger) @@ -70,7 +71,7 @@ func CloseCaches(caches map[string]cache.Cache) error { } // NewCache returns a Cache object based on the provided config.CachingConfig -func NewCache(cacheName string, cfg *options.Options, logger interface{}) cache.Cache { +func NewCache(cacheName string, cfg *options.Options, logger logging.Logger) cache.Cache { var c cache.Cache diff --git a/pkg/cache/registration/registration_test.go b/pkg/cache/registration/registration_test.go index 3b1acdef7..990325bc3 100644 --- a/pkg/cache/registration/registration_test.go +++ b/pkg/cache/registration/registration_test.go @@ -27,7 +27,7 @@ import ( "github.com/trickstercache/trickster/v2/pkg/cache/providers" ro "github.com/trickstercache/trickster/v2/pkg/cache/redis/options" "github.com/trickstercache/trickster/v2/pkg/config" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" ) func TestLoadCachesFromConfig(t *testing.T) { @@ -51,7 +51,7 @@ func TestLoadCachesFromConfig(t *testing.T) { } } - caches := LoadCachesFromConfig(conf, tl.ConsoleLogger("error")) + caches := LoadCachesFromConfig(conf, logging.ConsoleLogger("error")) defer CloseCaches(caches) _, ok := caches["default"] if !ok { diff --git a/pkg/config/reload/reload.go b/pkg/config/reload/reload.go index 40792dde1..ff08cf9e9 100644 --- a/pkg/config/reload/reload.go +++ b/pkg/config/reload/reload.go @@ -22,10 +22,10 @@ import ( "github.com/trickstercache/trickster/v2/pkg/cache" "github.com/trickstercache/trickster/v2/pkg/config" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" ) // ReloaderFunc describes a function that loads and applies a Trickster config at startup, // or gracefully over an existing running Config -type ReloaderFunc func(*config.Config, *sync.WaitGroup, *tl.Logger, +type ReloaderFunc func(*config.Config, *sync.WaitGroup, logging.Logger, map[string]cache.Cache, []string, func()) error diff --git a/pkg/httpserver/httpserver.go b/pkg/httpserver/httpserver.go index 700b30f70..8140b3d09 100644 --- a/pkg/httpserver/httpserver.go +++ b/pkg/httpserver/httpserver.go @@ -37,7 +37,8 @@ import ( "github.com/trickstercache/trickster/v2/pkg/config" ro "github.com/trickstercache/trickster/v2/pkg/config/reload/options" "github.com/trickstercache/trickster/v2/pkg/httpserver/signal" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging/level" "github.com/trickstercache/trickster/v2/pkg/observability/metrics" tr "github.com/trickstercache/trickster/v2/pkg/observability/tracing/registration" "github.com/trickstercache/trickster/v2/pkg/proxy/handlers" @@ -50,7 +51,7 @@ var hc healthcheck.HealthChecker var _ signal.ServeFunc = Serve -func Serve(oldConf *config.Config, wg *sync.WaitGroup, logger *tl.Logger, +func Serve(oldConf *config.Config, wg *sync.WaitGroup, logger logging.Logger, oldCaches map[string]cache.Cache, args []string, errorFunc func()) error { metrics.BuildInfo.WithLabelValues(goruntime.Version(), @@ -99,7 +100,7 @@ func Serve(oldConf *config.Config, wg *sync.WaitGroup, logger *tl.Logger, } -func applyConfig(conf, oldConf *config.Config, wg *sync.WaitGroup, logger *tl.Logger, +func applyConfig(conf, oldConf *config.Config, wg *sync.WaitGroup, logger logging.Logger, oldCaches map[string]cache.Cache, args []string, errorFunc func()) error { if conf == nil { @@ -118,13 +119,13 @@ func applyConfig(conf, oldConf *config.Config, wg *sync.WaitGroup, logger *tl.Lo logger = applyLoggingConfig(conf, oldConf, logger) for _, w := range conf.LoaderWarnings { - tl.Warn(logger, w, tl.Pairs{}) + logger.Warn(w, nil) } //Register Tracing Configurations tracers, err := tr.RegisterAll(conf, logger, false) if err != nil { - handleStartupIssue("tracing registration failed", tl.Pairs{"detail": err.Error()}, + handleStartupIssue("tracing registration failed", logging.Pairs{"detail": err.Error()}, logger, errorFunc) return err } @@ -143,7 +144,7 @@ func applyConfig(conf, oldConf *config.Config, wg *sync.WaitGroup, logger *tl.Lo o, err := routing.RegisterProxyRoutes(conf, r, mr, caches, tracers, logger, false) if err != nil { - handleStartupIssue("route registration failed", tl.Pairs{"detail": err.Error()}, + handleStartupIssue("route registration failed", logging.Pairs{"detail": err.Error()}, logger, errorFunc) return err } @@ -178,7 +179,7 @@ func applyConfig(conf, oldConf *config.Config, wg *sync.WaitGroup, logger *tl.Lo return nil } -func applyLoggingConfig(c, o *config.Config, oldLog *tl.Logger) *tl.Logger { +func applyLoggingConfig(c, o *config.Config, oldLog logging.Logger) logging.Logger { if c == nil || c.Logging == nil { return oldLog @@ -206,7 +207,7 @@ func applyLoggingConfig(c, o *config.Config, oldLog *tl.Logger) *tl.Logger { } if c.Logging.LogLevel != o.Logging.LogLevel { // the only change is the log level, so update it and return the original logger - oldLog.SetLogLevel(c.Logging.LogLevel) + oldLog.SetLogLevel(level.Level(c.Logging.LogLevel)) return oldLog } } @@ -214,7 +215,7 @@ func applyLoggingConfig(c, o *config.Config, oldLog *tl.Logger) *tl.Logger { return initLogger(c) } -func applyCachingConfig(c, oc *config.Config, logger *tl.Logger, +func applyCachingConfig(c, oc *config.Config, logger logging.Logger, oldCaches map[string]cache.Cache) map[string]cache.Cache { if c == nil { @@ -270,10 +271,10 @@ func applyCachingConfig(c, oc *config.Config, logger *tl.Logger, return caches } -func initLogger(c *config.Config) *tl.Logger { - logger := tl.New(c) - tl.Info(logger, "application loaded from configuration", - tl.Pairs{ +func initLogger(c *config.Config) logging.Logger { + logger := logging.New(c) + logger.Info("application loaded from configuration", + logging.Pairs{ "name": appinfo.Name, "version": appinfo.Version, "goVersion": goruntime.Version(), @@ -289,7 +290,7 @@ func initLogger(c *config.Config) *tl.Logger { return logger } -func delayedLogCloser(logger *tl.Logger, delay time.Duration) { +func delayedLogCloser(logger logging.Logger, delay time.Duration) { // we can't immediately close the logger, because some outstanding // http requests might still be on the old reference, so this will // allow time for those connections to drain @@ -300,15 +301,15 @@ func delayedLogCloser(logger *tl.Logger, delay time.Duration) { logger.Close() } -func handleStartupIssue(event string, detail tl.Pairs, logger *tl.Logger, errorFunc func()) { +func handleStartupIssue(event string, detail logging.Pairs, logger logging.Logger, errorFunc func()) { metrics.LastReloadSuccessful.Set(0) if event != "" { if logger != nil { if errorFunc != nil { - tl.Error(logger, event, detail) + logger.Error(event, detail) errorFunc() } - tl.Warn(logger, event, detail) + logger.Warn(event, detail) return } fmt.Println(event) @@ -332,7 +333,7 @@ func validateConfig(conf *config.Config) error { r := lm.NewRouter() mr := lm.NewRouter() mr.SetMatchingScheme(0) // metrics router is exact-match only - logger := tl.ConsoleLogger(conf.Logging.LogLevel) + logger := logging.ConsoleLogger(level.Info) tracers, err := tr.RegisterAll(conf, logger, true) if err != nil { diff --git a/pkg/httpserver/listeners.go b/pkg/httpserver/listeners.go index 23390812d..83fd35874 100644 --- a/pkg/httpserver/listeners.go +++ b/pkg/httpserver/listeners.go @@ -24,7 +24,7 @@ import ( "github.com/trickstercache/trickster/v2/pkg/backends" "github.com/trickstercache/trickster/v2/pkg/config" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" "github.com/trickstercache/trickster/v2/pkg/observability/metrics" "github.com/trickstercache/trickster/v2/pkg/observability/tracing" "github.com/trickstercache/trickster/v2/pkg/proxy/handlers" @@ -39,7 +39,7 @@ var lg = listener.NewListenerGroup() func applyListenerConfigs(conf, oldConf *config.Config, router, reloadHandler http.Handler, metricsRouter router.Router, - log *tl.Logger, tracers tracing.Tracers, o backends.Backends, + logger logging.Logger, tracers tracing.Tracers, o backends.Backends, wg *sync.WaitGroup, errorFunc func()) { var err error @@ -70,8 +70,8 @@ func applyListenerConfigs(conf, oldConf *config.Config, } if oldConf != nil && oldConf.Frontend.ConnectionsLimit != conf.Frontend.ConnectionsLimit { - tl.Warn(log, "connections limit change requires a process restart. listeners not updated.", - tl.Pairs{"oldLimit": oldConf.Frontend.ConnectionsLimit, + logger.Warn("connections limit change requires a process restart. listeners not updated.", + logging.Pairs{"oldLimit": oldConf.Frontend.ConnectionsLimit, "newLimit": conf.Frontend.ConnectionsLimit}) return } @@ -91,14 +91,15 @@ func applyListenerConfigs(conf, oldConf *config.Config, lg.DrainAndClose("tlsListener", drainTimeout) tlsConfig, err = conf.TLSCertConfig() if err != nil { - tl.Error(log, "unable to start tls listener due to certificate error", tl.Pairs{"detail": err}) + logger.Error("unable to start tls listener due to certificate error", + logging.Pairs{"detail": err}) } else { wg.Add(1) tracerFlusherSet = true go lg.StartListener("tlsListener", conf.Frontend.TLSListenAddress, conf.Frontend.TLSListenPort, conf.Frontend.ConnectionsLimit, tlsConfig, router, wg, tracers, errorFunc, - time.Duration(conf.ReloadConfig.DrainTimeoutMS)*time.Millisecond, log) + time.Duration(conf.ReloadConfig.DrainTimeoutMS)*time.Millisecond, logger) } } else if !conf.Frontend.ServeTLS && hasOldFC && oldConf.Frontend.ServeTLS { // the TLS configs have been removed between the last config load and this one, @@ -107,7 +108,8 @@ func applyListenerConfigs(conf, oldConf *config.Config, } else if conf.Frontend.ServeTLS && ttls.OptionsChanged(conf, oldConf) { tlsConfig, err = conf.TLSCertConfig() if err != nil { - tl.Error(log, "unable to update tls config to certificate error", tl.Pairs{"detail": err}) + logger.Error("unable to update tls config to certificate error", + logging.Pairs{"detail": err}) return } l := lg.Get("tlsListener") @@ -131,7 +133,7 @@ func applyListenerConfigs(conf, oldConf *config.Config, } go lg.StartListener("httpListener", conf.Frontend.ListenAddress, conf.Frontend.ListenPort, - conf.Frontend.ConnectionsLimit, nil, router, wg, t2, errorFunc, 0, log) + conf.Frontend.ConnectionsLimit, nil, router, wg, t2, errorFunc, 0, logger) } // if the Metrics HTTP port is configured, then set up the http listener instance @@ -144,12 +146,12 @@ func applyListenerConfigs(conf, oldConf *config.Config, metricsRouter.RegisterRoute(conf.Main.ConfigHandlerPath, nil, nil, false, http.HandlerFunc(handlers.ConfigHandleFunc(conf))) if conf.Main.PprofServer == "both" || conf.Main.PprofServer == "metrics" { - routing.RegisterPprofRoutes("metrics", metricsRouter, log) + routing.RegisterPprofRoutes("metrics", metricsRouter, logger) } wg.Add(1) go lg.StartListener("metricsListener", conf.Metrics.ListenAddress, conf.Metrics.ListenPort, - conf.Frontend.ConnectionsLimit, nil, metricsRouter, wg, nil, errorFunc, 0, log) + conf.Frontend.ConnectionsLimit, nil, metricsRouter, wg, nil, errorFunc, 0, logger) } else { metricsRouter.RegisterRoute("/metrics", nil, nil, false, metrics.Handler()) @@ -174,11 +176,11 @@ func applyListenerConfigs(conf, oldConf *config.Config, rr.RegisterRoute(conf.Main.PurgePathHandlerPath, nil, nil, false, http.HandlerFunc(handlers.PurgePathHandlerFunc(conf, &o))) if conf.Main.PprofServer == "both" || conf.Main.PprofServer == "reload" { - routing.RegisterPprofRoutes("reload", rr, log) + routing.RegisterPprofRoutes("reload", rr, logger) } go lg.StartListener("reloadListener", conf.ReloadConfig.ListenAddress, conf.ReloadConfig.ListenPort, - conf.Frontend.ConnectionsLimit, nil, rr, wg, nil, errorFunc, 0, log) + conf.Frontend.ConnectionsLimit, nil, rr, wg, nil, errorFunc, 0, logger) } else { rr.RegisterRoute(conf.Main.ConfigHandlerPath, nil, nil, false, http.HandlerFunc(handlers.ConfigHandleFunc(conf))) diff --git a/pkg/httpserver/signal/signal.go b/pkg/httpserver/signal/signal.go index 9278db134..1c48acb49 100644 --- a/pkg/httpserver/signal/signal.go +++ b/pkg/httpserver/signal/signal.go @@ -24,7 +24,7 @@ import ( "github.com/trickstercache/trickster/v2/pkg/cache" "github.com/trickstercache/trickster/v2/pkg/config" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" ) var hups = make(chan os.Signal, 1) @@ -33,10 +33,10 @@ func init() { signal.Notify(hups, syscall.SIGHUP) } -type ServeFunc = func(*config.Config, *sync.WaitGroup, *tl.Logger, +type ServeFunc = func(*config.Config, *sync.WaitGroup, logging.Logger, map[string]cache.Cache, []string, func()) error -func StartHupMonitor(conf *config.Config, wg *sync.WaitGroup, log *tl.Logger, +func StartHupMonitor(conf *config.Config, wg *sync.WaitGroup, logger logging.Logger, caches map[string]cache.Cache, args []string, f ServeFunc) { if conf == nil || conf.Resources == nil || f == nil { return @@ -48,15 +48,16 @@ func StartHupMonitor(conf *config.Config, wg *sync.WaitGroup, log *tl.Logger, case <-hups: conf.Main.ReloaderLock.Lock() if conf.IsStale() { - tl.Warn(log, "configuration reload starting now", tl.Pairs{"source": "sighup"}) - err := f(conf, wg, log, caches, args, nil) + logger.Warn("configuration reload starting now", + logging.Pairs{"source": "sighup"}) + err := f(conf, wg, logger, caches, args, nil) if err == nil { conf.Main.ReloaderLock.Unlock() return // runConfig will start a new HupMonitor in place of this one } } conf.Main.ReloaderLock.Unlock() - tl.Warn(log, "configuration NOT reloaded", tl.Pairs{}) + logger.Warn("configuration NOT reloaded", nil) case <-conf.Resources.QuitChan: return } diff --git a/pkg/httpserver/signal/signal_test.go b/pkg/httpserver/signal/signal_test.go index 5b0634254..8164d7d56 100644 --- a/pkg/httpserver/signal/signal_test.go +++ b/pkg/httpserver/signal/signal_test.go @@ -26,10 +26,9 @@ import ( "github.com/trickstercache/trickster/v2/pkg/cache" "github.com/trickstercache/trickster/v2/pkg/config" "github.com/trickstercache/trickster/v2/pkg/observability/logging" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" ) -func mockServe(oldConf *config.Config, wg *sync.WaitGroup, logger *tl.Logger, +func mockServe(oldConf *config.Config, wg *sync.WaitGroup, logger logging.Logger, oldCaches map[string]cache.Cache, args []string, errorFunc func()) error { return nil } diff --git a/pkg/observability/logging/level/level.go b/pkg/observability/logging/level/level.go new file mode 100644 index 000000000..b94f43037 --- /dev/null +++ b/pkg/observability/logging/level/level.go @@ -0,0 +1,35 @@ +package level + +import "strings" + +type Level string +type LevelID int + +const ( + Debug Level = "debug" + Info Level = "info" + Warn Level = "warn" + Error Level = "error" + Fatal Level = "fatal" + + DebugID LevelID = 1 + InfoID LevelID = 2 + WarnID LevelID = 3 + ErrorID LevelID = 4 + TraceID LevelID = 5 +) + +var validLevels = map[Level]LevelID{ + Debug: DebugID, + Info: InfoID, + Warn: WarnID, + Error: ErrorID, + Fatal: TraceID, +} + +func GetLevelID(logLevel Level) LevelID { + if i, ok := validLevels[Level(strings.ToLower(string(logLevel)))]; ok { + return i + } + return 0 +} diff --git a/pkg/observability/logging/logging.go b/pkg/observability/logging/logging.go index af4a54618..db0aa9ab0 100644 --- a/pkg/observability/logging/logging.go +++ b/pkg/observability/logging/logging.go @@ -1,423 +1,362 @@ -/* - * Copyright 2018 The Trickster Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// Package logging provides logging functionality to Trickster package logging import ( "fmt" "io" - "log" "os" + "slices" "strconv" "strings" "sync" + "time" "github.com/trickstercache/trickster/v2/pkg/config" + "github.com/trickstercache/trickster/v2/pkg/observability/logging/level" - gkl "github.com/go-kit/log" - "github.com/go-kit/log/level" - "github.com/go-stack/stack" lumberjack "gopkg.in/natefinch/lumberjack.v2" ) -// Logger is a container for the underlying log provider -type Logger struct { - baseLogger gkl.Logger // the logger prior to leveling, used to relevel in config reload - logger gkl.Logger // the logger after leveling, which is used by importing packages - closer io.Closer - level string +var _ Logger = &logger{} +var _ io.Writer = &logger{} + +type Logger interface { + // + SetLogLevel(level.Level) + SetLogAsynchronous(bool) + // + Level() level.Level + Close() + // + Log(logLevel level.Level, event string, detail Pairs) + Debug(event string, detail Pairs) + Info(event string, detail Pairs) + Warn(event string, detail Pairs) + Error(event string, detail Pairs) + Fatal(code int, event string, detail Pairs) + // + // These funcs log synchronously even if the logger is set to Asynchronous + LogSynchronous(logLevel level.Level, event string, detail Pairs) + DebugSynchronous(event string, detail Pairs) + InfoSynchronous(event string, detail Pairs) + WarnSynchronous(event string, detail Pairs) + ErrorSynchronous(event string, detail Pairs) + // + LogOnce(logLevel level.Level, key, event string, detail Pairs) bool + DebugOnce(key, event string, detail Pairs) bool + InfoOnce(key, event string, detail Pairs) bool + WarnOnce(key, event string, detail Pairs) bool + ErrorOnce(key, event string, detail Pairs) bool + // + HasLoggedOnce(logLevel level.Level, key string) bool + HasDebuggedOnce(key string) bool + HasInfoedOnce(key string) bool + HasWarnedOnce(key string) bool + HasErroredOnce(key string) bool +} - onceMutex *sync.Mutex - mtx sync.Mutex - onceRanEntries map[string]interface{} +type logFunc func(level.Level, string, Pairs) + +// Pairs represents a key=value pair that helps to describe a log event +type Pairs map[string]any + +// New returns a Logger for the provided logging configuration. The +// returned Logger will write to files distinguished from other Loggers by the +// instance string. +func New(conf *config.Config) Logger { + l := &logger{ + onceRanEntries: make(map[string]any), + } + l.logFunc = l.logAsyncronous + if conf.Logging.LogFile == "" { + l.writer = os.Stdout + } else { + logFile := conf.Logging.LogFile + if conf.Main.InstanceID > 0 { + logFile = strings.Replace(logFile, ".log", + "."+strconv.Itoa(conf.Main.InstanceID)+".log", 1) + } + l.writer = &lumberjack.Logger{ + Filename: logFile, + MaxSize: 256, // megabytes + MaxBackups: 80, // 256 megs @ 80 backups is 20GB of Logs + MaxAge: 7, // days + Compress: true, // Compress Rolled Backups + } + } + if c, ok := l.writer.(io.Closer); ok && c != nil { + l.closer = c + } + l.SetLogLevel(level.Level(conf.Logging.LogLevel)) + return l } -// SyncLogger is a Logger that writes synchronously -type SyncLogger struct { - *Logger +func NoopLogger() Logger { + l := &logger{ + logFunc: func(level.Level, string, Pairs) {}, + onceRanEntries: make(map[string]any), + levelID: level.InfoID, + level: level.Info, + } + return l } -func Debug(logger interface{}, event string, detail Pairs) { - if logger == nil { - return +func StreamLogger(w io.Writer, logLevel level.Level) Logger { + l := &logger{ + writer: w, + onceRanEntries: make(map[string]any), } - detail["caller"] = pkgCaller{stack.Caller(1)} - switch l := logger.(type) { - case *Logger: - go l.Debug(event, detail) - case *SyncLogger: - l.Debug(event, detail) - case *log.Logger: - go l.Print("") - case gkl.Logger: - go level.Debug(l).Log(detail.ToList(event)...) + l.logFunc = l.logAsyncronous + + if c, ok := l.writer.(io.Closer); ok && c != nil { + l.closer = c } + l.SetLogLevel(logLevel) + return l } -func Info(logger interface{}, event string, detail Pairs) { - if logger == nil { - return +func ConsoleLogger(logLevel level.Level) Logger { + l := &logger{ + writer: os.Stdout, + onceRanEntries: make(map[string]any), } - detail["caller"] = pkgCaller{stack.Caller(1)} - switch l := logger.(type) { - case *Logger: - go l.Info(event, detail) - case *SyncLogger: - l.Info(event, detail) - case *log.Logger: - go l.Print("") - case gkl.Logger: - go level.Info(l).Log(detail.ToList(event)...) + l.logFunc = l.logAsyncronous + l.SetLogLevel(logLevel) + return l +} + +type logger struct { + level level.Level + levelID level.LevelID + writer io.Writer + closer io.Closer + onceMutex sync.Mutex + mtx sync.Mutex + onceRanEntries map[string]any + logFunc logFunc +} + +func (l *logger) Write(b []byte) (int, error) { + if l.writer == nil { + return 0, nil } + return l.writer.Write(b) } -func Warn(logger interface{}, event string, detail Pairs) { - if logger == nil { - return +func (l *logger) SetLogLevel(logLevel level.Level) { + id := level.GetLevelID(logLevel) + if id == 0 { + l.WarnOnce("loglevel."+string(logLevel), + "unknown log level; using INFO", + Pairs{"providedLevel": logLevel}) + logLevel = level.Info + id = level.InfoID } - detail["caller"] = pkgCaller{stack.Caller(1)} - switch l := logger.(type) { - case *Logger: - go l.Warn(event, detail) - case *SyncLogger: - l.Warn(event, detail) - case *log.Logger: - go l.Print("") - case gkl.Logger: - go level.Warn(l).Log(detail.ToList(event)...) + l.level = logLevel + l.levelID = id +} + +func (l *logger) SetLogAsynchronous(asyncEnabled bool) { + if asyncEnabled { + l.logFunc = l.logAsyncronous + } else { + l.logFunc = l.log } } -func WarnOnce(logger interface{}, key string, event string, detail Pairs) { - if logger == nil { +func (l *logger) Log(logLevel level.Level, event string, detail Pairs) { + lid := level.GetLevelID(logLevel) + if lid == 0 || lid < l.levelID { return } - detail["caller"] = pkgCaller{stack.Caller(1)} - switch l := logger.(type) { - case *Logger: // must be Synchronous to avoid double writes - l.WarnOnce(key, event, detail) - case *SyncLogger: // must be Synchronous to avoid double writes - l.WarnOnce(key, event, detail) - case *log.Logger: - go l.Print("") - case gkl.Logger: - go level.Warn(l).Log(detail.ToList(event)...) - } + l.logFunc(logLevel, event, detail) } -func Error(logger interface{}, event string, detail Pairs) { - if logger == nil { +func (l *logger) Debug(event string, detail Pairs) { + if l.levelID > level.DebugID { return } - detail["caller"] = pkgCaller{stack.Caller(1)} - switch l := logger.(type) { - case *Logger: - go l.Error(event, detail) - case *SyncLogger: - l.Error(event, detail) - case *log.Logger: - go l.Print("") - case gkl.Logger: - go level.Error(l).Log(detail.ToList(event)...) - } + l.logFunc(level.Debug, event, detail) } -func ErrorSynchronous(logger interface{}, event string, detail Pairs) { - if logger == nil { +func (l *logger) Info(event string, detail Pairs) { + if l.levelID > level.InfoID { return } - detail["caller"] = pkgCaller{stack.Caller(1)} - switch l := logger.(type) { - case *Logger: - l.Error(event, detail) - case *SyncLogger: - l.Error(event, detail) - case *log.Logger: - l.Print("") - case gkl.Logger: - level.Error(l).Log(detail.ToList(event)...) - } + l.logFunc(level.Info, event, detail) } -// Fatal sends a "FATAL" event to the Logger and exits the program with the provided exit code -func Fatal(logger interface{}, code int, event string, detail Pairs) { - // go-kit/log/level does not support Fatal, so implemented separately here - detail["level"] = "fatal" - detail["caller"] = pkgCaller{stack.Caller(1)} - switch l := logger.(type) { - case *Logger: - l.Fatal(code, event, detail) - case *SyncLogger: - l.Fatal(code, event, detail) - case *log.Logger: - l.Print("") - case gkl.Logger: - level.Error(l).Log(detail.ToList(event)...) - } - if code >= 0 { - os.Exit(code) +func (l *logger) Warn(event string, detail Pairs) { + if l.levelID > level.WarnID { + return } + l.logFunc(level.Warn, event, detail) } -func (p Pairs) ToList(event string) []interface{} { - a := make([]interface{}, (len(p)*2)+2) - var i int - // Ensure the log level is the first Pair in the output order (after prefixes) - if level, ok := p["level"]; ok { - a[0] = "level" - a[1] = level - i += 2 - } - // Ensure the event description is the second Pair in the output order (after prefixes) - a[i] = "event" - a[i+1] = event - i += 2 - for k, v := range p { - if k == "level" { - continue - } - a[i] = k - a[i+1] = v - i += 2 +func (l *logger) Error(event string, detail Pairs) { + if l.levelID > level.ErrorID { + return } - return a + l.logFunc(level.Error, event, detail) } -// DefaultLogger returns the default logger, which is the console logger at level "info" -func DefaultLogger() *Logger { - return ConsoleLogger("info") +func (l *logger) LogSynchronous(logLevel level.Level, event string, detail Pairs) { + lid := level.GetLevelID(logLevel) + if lid == 0 || lid < l.levelID { + return + } + l.log(logLevel, event, detail) + } -func noopLogger() *Logger { - return &Logger{ - onceRanEntries: make(map[string]interface{}), - onceMutex: &sync.Mutex{}, +func (l *logger) DebugSynchronous(event string, detail Pairs) { + if l.levelID > level.DebugID { + return } + l.log(level.Debug, event, detail) } -func StreamLogger(w io.Writer, logLevel string) *Logger { - l := noopLogger() - l.baseLogger = gkl.NewLogfmtLogger(gkl.NewSyncWriter(w)) - l.baseLogger = gkl.With(l.baseLogger, - "time", gkl.DefaultTimestampUTC, - "app", "trickster", - ) - l.SetLogLevel(logLevel) - return l +func (l *logger) InfoSynchronous(event string, detail Pairs) { + if l.levelID > level.InfoID { + return + } + l.log(level.Info, event, detail) } -// ConsoleLogger returns a Logger object that prints log events to the Console -func ConsoleLogger(logLevel string) *Logger { - - l := noopLogger() - wr := os.Stdout - l.baseLogger = gkl.NewLogfmtLogger(gkl.NewSyncWriter(wr)) - l.baseLogger = gkl.With(l.baseLogger, - "time", gkl.DefaultTimestampUTC, - "app", "trickster", - ) - l.SetLogLevel(logLevel) - return l +func (l *logger) WarnSynchronous(event string, detail Pairs) { + if l.levelID > level.WarnID { + return + } + l.log(level.Warn, event, detail) } -// SetLogLevel sets the log level, defaulting to "Info" if the provided level is unknown -func (tl *Logger) SetLogLevel(logLevel string) { - tl.level = strings.ToLower(logLevel) - // wrap logger depending on log level - switch tl.level { - case "debug": - tl.logger = level.NewFilter(tl.baseLogger, level.AllowDebug()) - case "info": - tl.logger = level.NewFilter(tl.baseLogger, level.AllowInfo()) - case "warn": - tl.logger = level.NewFilter(tl.baseLogger, level.AllowWarn()) - case "error": - tl.logger = level.NewFilter(tl.baseLogger, level.AllowError()) - case "trace": - tl.logger = level.NewFilter(tl.baseLogger, level.AllowDebug()) - case "none": - tl.logger = level.NewFilter(tl.baseLogger, level.AllowNone()) - default: - tl.logger = level.NewFilter(tl.baseLogger, level.AllowInfo()) +func (l *logger) ErrorSynchronous(event string, detail Pairs) { + if l.levelID > level.ErrorID { + return } + l.log(level.Error, event, detail) } -// New returns a Logger for the provided logging configuration. The -// returned Logger will write to files distinguished from other Loggers by the -// instance string. -func New(conf *config.Config) *Logger { - - l := noopLogger() - var wr io.Writer +func (l *logger) Fatal(code int, event string, detail Pairs) { + l.log(level.Fatal, event, detail) + if code < 0 { + // tests will send a -1 code to avoid a panic during the test + return + } + if code == 0 { + code = 1 + } + os.Exit(code) +} - if conf.Logging.LogFile == "" { - wr = os.Stdout - } else { - logFile := conf.Logging.LogFile - if conf.Main.InstanceID > 0 { - logFile = strings.Replace(logFile, ".log", "."+strconv.Itoa(conf.Main.InstanceID)+".log", 1) - } +func (l *logger) LogOnce(logLevel level.Level, key, event string, detail Pairs) bool { + lid := level.GetLevelID(logLevel) + return l.logOnce(logLevel, lid, key, event, detail) +} - wr = &lumberjack.Logger{ - Filename: logFile, - MaxSize: 256, // megabytes - MaxBackups: 80, // 256 megs @ 80 backups is 20GB of Logs - MaxAge: 7, // days - Compress: true, // Compress Rolled Backups - } +func (l *logger) logOnce(logLevel level.Level, lid level.LevelID, + key, event string, detail Pairs) bool { + if lid == 0 || lid < l.levelID || l.HasLoggedOnce(logLevel, key) { + return false } + key = string(logLevel) + "." + key + l.onceMutex.Lock() + l.onceRanEntries[key] = nil + l.onceMutex.Unlock() + l.logFunc(logLevel, event, detail) + return true +} - l.baseLogger = gkl.NewLogfmtLogger(gkl.NewSyncWriter(wr)) - l.baseLogger = gkl.With(l.baseLogger, - "time", gkl.DefaultTimestampUTC, - "app", "trickster", - ) - - l.SetLogLevel(conf.Logging.LogLevel) +func (l *logger) DebugOnce(key, event string, detail Pairs) bool { + return l.logOnce(level.Debug, level.DebugID, key, event, detail) +} - if c, ok := wr.(io.Closer); ok && c != nil { - l.closer = c - } +func (l *logger) InfoOnce(key, event string, detail Pairs) bool { + return l.logOnce(level.Info, level.InfoID, key, event, detail) +} - return l +func (l *logger) WarnOnce(key, event string, detail Pairs) bool { + return l.logOnce(level.Warn, level.WarnID, key, event, detail) } -// Pairs represents a key=value pair that helps to describe a log event -type Pairs map[string]interface{} - -// Info sends an "INFO" event to the Logger -func (tl *Logger) Info(event string, detail Pairs) { - tl.mtx.Lock() - level.Info(tl.logger).Log(detail.ToList(event)...) - tl.mtx.Unlock() -} - -// InfoOnce sends a "INFO" event to the Logger only once per key. -// Returns true if this invocation was the first, and thus sent to the Logger -func (tl *Logger) InfoOnce(key string, event string, detail Pairs) bool { - tl.onceMutex.Lock() - defer tl.onceMutex.Unlock() - key = "info." + key - if _, ok := tl.onceRanEntries[key]; !ok { - tl.onceRanEntries[key] = nil - tl.Info(event, detail) - return true - } - return false -} - -// Warn sends an "WARN" event to the Logger -func (tl *Logger) Warn(event string, detail Pairs) { - tl.mtx.Lock() - level.Warn(tl.logger).Log(detail.ToList(event)...) - tl.mtx.Unlock() -} - -// WarnOnce sends a "WARN" event to the Logger only once per key. -// Returns true if this invocation was the first, and thus sent to the Logger -func (tl *Logger) WarnOnce(key string, event string, detail Pairs) bool { - tl.onceMutex.Lock() - defer tl.onceMutex.Unlock() - key = "warn." + key - if _, ok := tl.onceRanEntries[key]; !ok { - tl.onceRanEntries[key] = nil - tl.Warn(event, detail) - return true - } - return false +func (l *logger) ErrorOnce(key, event string, detail Pairs) bool { + return l.logOnce(level.Error, level.ErrorID, key, event, detail) } -// HasWarnedOnce returns true if a warning for the key has already been sent to the Logger -func (tl *Logger) HasWarnedOnce(key string) bool { - tl.onceMutex.Lock() - defer tl.onceMutex.Unlock() - key = "warn." + key - _, ok := tl.onceRanEntries[key] - return ok +func (l *logger) HasDebuggedOnce(key string) bool { + return l.HasLoggedOnce(level.Debug, key) } -// Error sends an "ERROR" event to the Logger -func (tl *Logger) Error(event string, detail Pairs) { - tl.mtx.Lock() - level.Error(tl.logger).Log(detail.ToList(event)...) - tl.mtx.Unlock() +func (l *logger) HasInfoedOnce(key string) bool { + return l.HasLoggedOnce(level.Info, key) } -// ErrorOnce sends an "ERROR" event to the Logger only once per key -// Returns true if this invocation was the first, and thus sent to the Logger -func (tl *Logger) ErrorOnce(key string, event string, detail Pairs) bool { - tl.onceMutex.Lock() - defer tl.onceMutex.Unlock() - key = "error." + key - if _, ok := tl.onceRanEntries[key]; !ok { - tl.onceRanEntries[key] = nil - tl.Error(event, detail) - return true - } - return false +func (l *logger) HasWarnedOnce(key string) bool { + return l.HasLoggedOnce(level.Warn, key) } -// Debug sends an "DEBUG" event to the Logger -func (tl *Logger) Debug(event string, detail Pairs) { - tl.mtx.Lock() - level.Debug(tl.logger).Log(detail.ToList(event)...) - tl.mtx.Unlock() +func (l *logger) HasErroredOnce(key string) bool { + return l.HasLoggedOnce(level.Error, key) } -// Trace sends a "TRACE" event to the Logger -func (tl *Logger) Trace(event string, detail Pairs) { - tl.mtx.Lock() - // go-kit/log/level does not support Trace, so implemented separately here - if tl.level == "trace" { - detail["level"] = "trace" - tl.logger.Log(detail.ToList(event)...) - } - tl.mtx.Unlock() +func (l *logger) HasLoggedOnce(logLevel level.Level, key string) bool { + key = string(logLevel) + "." + key + l.onceMutex.Lock() + _, ok := l.onceRanEntries[key] + l.onceMutex.Unlock() + return ok } -// Fatal sends a "FATAL" event to the Logger and exits the program with the provided exit code -func (tl *Logger) Fatal(code int, event string, detail Pairs) { - // go-kit/log/level does not support Fatal, so implemented separately here - detail["level"] = "fatal" - tl.logger.Log(detail.ToList(event)...) - if code >= 0 { - os.Exit(code) - } +func (l *logger) logAsyncronous(logLevel level.Level, event string, detail Pairs) { + go l.log(logLevel, event, detail) } -// Level returns the configured Log Level -func (tl *Logger) Level() string { - return tl.level +const defaultLogItemCount = 4 + +func (l *logger) log(logLevel level.Level, event string, detail Pairs) { + if l.writer == nil { + return + } + ts := time.Now() + ld := len(detail) + keys := make([]string, defaultLogItemCount, ld+defaultLogItemCount) + keys[0] = "time=" + ts.UTC().Format(time.RFC3339Nano) + keys[1] = "app=trickster" + keys[2] = "level=" + string(logLevel) + if strings.HasPrefix(event, " ") || strings.HasSuffix(event, " ") { + event = strings.TrimSpace(event) + } + keys[3] = "event=" + quoteAsNeeded(event) + var i int + if ld > 0 { + sortedKeys := make([]string, ld) + for k, v := range detail { + if s, ok := v.(string); ok && strings.Contains(s, " ") { + v = `"` + s + `"` + } + sortedKeys[i] = fmt.Sprintf("%s=%v", k, v) + i++ + } + slices.Sort(sortedKeys) + keys = append(keys, sortedKeys...) + } + l.mtx.Lock() + l.writer.Write([]byte(strings.Join(keys, " ") + "\n")) + l.mtx.Unlock() } -// Close closes any opened file handles that were used for logging. -func (tl *Logger) Close() { - if tl.closer != nil { - tl.closer.Close() +func quoteAsNeeded(input string) string { + if !strings.Contains(input, " ") { + return input } + return `"` + input + `"` } -// pkgCaller wraps a stack.Call to make the default string output include the -// package path. -type pkgCaller struct { - c stack.Call +func (l *logger) Level() level.Level { + return l.level } -// String returns a path from the call stack that is relative to the root of the project -func (pc pkgCaller) String() string { - return strings.TrimPrefix(fmt.Sprintf("%+v", pc.c), "github.com/trickstercache/trickster/pkg/") +func (l *logger) Close() { + if l.closer != nil { + l.closer.Close() + } } diff --git a/pkg/observability/logging/logging_test.go b/pkg/observability/logging/logging_test.go index 8910a7c34..d82f01ced 100644 --- a/pkg/observability/logging/logging_test.go +++ b/pkg/observability/logging/logging_test.go @@ -17,16 +17,13 @@ package logging import ( - "log" "net/http/httptest" "os" "testing" - "time" "github.com/trickstercache/trickster/v2/pkg/config" + "github.com/trickstercache/trickster/v2/pkg/observability/logging/level" "github.com/trickstercache/trickster/v2/pkg/observability/logging/options" - - gkl "github.com/go-kit/log" ) func TestConsoleLogger(t *testing.T) { @@ -36,15 +33,14 @@ func TestConsoleLogger(t *testing.T) { "info", "warn", "error", - "trace", - "none", } // it should create a logger for each level for _, tc := range testCases { t.Run(tc, func(t *testing.T) { - l := ConsoleLogger(tc) - if l.level != tc { - t.Errorf("mismatch in log level: expected=%s actual=%s", tc, l.level) + ltc := level.Level(tc) + l := ConsoleLogger(ltc) + if l.Level() != ltc { + t.Errorf("mismatch in log level: expected=%s actual=%s", tc, l.Level()) } }) } @@ -55,8 +51,8 @@ func TestNew(t *testing.T) { conf.Main = &config.MainConfig{InstanceID: 0} conf.Logging = &options.Options{LogLevel: "info"} logger := New(conf) - if logger.level != "info" { - t.Errorf("expected %s got %s", "info", logger.level) + if logger.Level() != level.Info { + t.Errorf("expected %s got %s", "info", logger.Level()) } } @@ -68,8 +64,9 @@ func TestNewLogger_LogFile(t *testing.T) { conf := config.NewConfig() conf.Main = &config.MainConfig{InstanceID: 1} conf.Logging = &options.Options{LogFile: fileName, LogLevel: "info"} - logger := &SyncLogger{Logger: New(conf)} - Info(logger, "test entry", Pairs{"testKey": "testVal"}) + logger := New(conf) + logger.SetLogAsynchronous(false) + logger.Info("testEntry ", Pairs{"testKey": "test Val", "testKey2": "testValue2"}) if _, err := os.Stat(instanceFileName); err != nil { t.Errorf(err.Error()) } @@ -82,7 +79,8 @@ func TestNewLoggerDebug_LogFile(t *testing.T) { conf := config.NewConfig() conf.Main = &config.MainConfig{InstanceID: 0} conf.Logging = &options.Options{LogFile: fileName, LogLevel: "debug"} - logger := &SyncLogger{Logger: New(conf)} + logger := New(conf) + logger.SetLogAsynchronous(false) logger.Debug("test entry", Pairs{"testKey": "testVal"}) if _, err := os.Stat(fileName); err != nil { t.Errorf(err.Error()) @@ -96,7 +94,8 @@ func TestNewLoggerWarn_LogFile(t *testing.T) { conf := config.NewConfig() conf.Main = &config.MainConfig{InstanceID: 0} conf.Logging = &options.Options{LogFile: fileName, LogLevel: "warn"} - logger := &SyncLogger{Logger: New(conf)} + logger := New(conf) + logger.SetLogAsynchronous(false) logger.Warn("test entry", Pairs{"testKey": "testVal"}) if _, err := os.Stat(fileName); err != nil { t.Errorf(err.Error()) @@ -110,8 +109,8 @@ func TestNewLoggerWarnOnce_LogFile(t *testing.T) { conf := config.NewConfig() conf.Main = &config.MainConfig{InstanceID: 0} conf.Logging = &options.Options{LogFile: fileName, LogLevel: "x"} - logger := &SyncLogger{Logger: New(conf)} - + logger := New(conf) + logger.SetLogAsynchronous(false) key := "warnonce-test-key" if logger.HasWarnedOnce(key) { @@ -148,7 +147,8 @@ func TestNewLoggerError_LogFile(t *testing.T) { conf := config.NewConfig() conf.Main = &config.MainConfig{InstanceID: 0} conf.Logging = &options.Options{LogFile: fileName, LogLevel: "error"} - logger := &SyncLogger{Logger: New(conf)} + logger := New(conf) + logger.SetLogAsynchronous(false) logger.Error("test entry", Pairs{"testKey": "testVal"}) if _, err := os.Stat(fileName); err != nil { t.Errorf(err.Error()) @@ -162,7 +162,8 @@ func TestNewLoggerErrorOnce_LogFile(t *testing.T) { conf := config.NewConfig() conf.Main = &config.MainConfig{InstanceID: 0} conf.Logging = &options.Options{LogFile: fileName, LogLevel: "x"} - logger := &SyncLogger{Logger: New(conf)} + logger := New(conf) + logger.SetLogAsynchronous(false) ok := logger.ErrorOnce("erroroonce-test-key", "test entry", Pairs{"testKey": "testVal"}) if !ok { @@ -180,27 +181,14 @@ func TestNewLoggerErrorOnce_LogFile(t *testing.T) { logger.Close() } -func TestNewLoggerTrace_LogFile(t *testing.T) { - fileName := t.TempDir() + "/out.trace.log" - // it should create a logger that outputs to a log file ("out.test.log") - conf := config.NewConfig() - conf.Main = &config.MainConfig{InstanceID: 0} - conf.Logging = &options.Options{LogFile: fileName, LogLevel: "trace"} - logger := &SyncLogger{Logger: New(conf)} - logger.Trace("test entry", Pairs{"testKey": "testVal"}) - if _, err := os.Stat(fileName); err != nil { - t.Errorf(err.Error()) - } - logger.Close() -} - func TestNewLoggerDefault_LogFile(t *testing.T) { fileName := t.TempDir() + "/out.info.log" // it should create a logger that outputs to a log file ("out.test.log") conf := config.NewConfig() conf.Main = &config.MainConfig{InstanceID: 0} conf.Logging = &options.Options{LogFile: fileName, LogLevel: "x"} - logger := &SyncLogger{Logger: New(conf)} + logger := New(conf) + logger.SetLogAsynchronous(false) logger.Info("test entry", Pairs{"testKey": "testVal"}) if _, err := os.Stat(fileName); err != nil { t.Errorf(err.Error()) @@ -214,7 +202,8 @@ func TestNewLoggerInfoOnce_LogFile(t *testing.T) { conf := config.NewConfig() conf.Main = &config.MainConfig{InstanceID: 0} conf.Logging = &options.Options{LogFile: fileName, LogLevel: "info"} - logger := &SyncLogger{Logger: New(conf)} + logger := New(conf) + logger.SetLogAsynchronous(false) ok := logger.InfoOnce("infoonce-test-key", "test entry", Pairs{"testKey": "testVal"}) if !ok { t.Errorf("expected %t got %t", true, ok) @@ -238,7 +227,8 @@ func TestNewLoggerFatal_LogFile(t *testing.T) { conf := config.NewConfig() conf.Main = &config.MainConfig{InstanceID: 0} conf.Logging = &options.Options{LogFile: fileName, LogLevel: "debug"} - logger := &SyncLogger{Logger: New(conf)} + logger := New(conf) + logger.SetLogAsynchronous(false) logger.Fatal(-1, "test entry", Pairs{"testKey": "testVal"}) if _, err := os.Stat(fileName); err != nil { t.Errorf(err.Error()) @@ -248,99 +238,22 @@ func TestNewLoggerFatal_LogFile(t *testing.T) { func TestSetLogLevel(t *testing.T) { - l := DefaultLogger() - if l.level != "info" { - t.Errorf("expected %s got %s", "info", l.level) + l := ConsoleLogger(level.Info) + if l.Level() != level.Info { + t.Errorf("expected %s got %s", "info", l.Level()) } l.SetLogLevel("warn") if l.Level() != "warn" { - t.Errorf("expected %s got %s", "warn", l.level) - } - -} - -func TestDebug(t *testing.T) { - testLogFunction(Debug, nil, nil, "DEBUG", t) -} - -func TestInfo(t *testing.T) { - testLogFunction(Info, nil, nil, "INFO", t) -} - -func TestWarn(t *testing.T) { - testLogFunction(Warn, WarnOnce, nil, "WARN", t) -} - -func TestError(t *testing.T) { - testLogFunction(Error, nil, nil, "ERROR", t) -} - -func TestFatal(t *testing.T) { - testLogFunction(nil, nil, Fatal, "ERROR", t) -} - -type basicLogFunc func(interface{}, string, Pairs) -type onceLogFunc func(interface{}, string, string, Pairs) -type fatalLogFunc func(interface{}, int, string, Pairs) - -func testLogFunction(f1 basicLogFunc, f2 onceLogFunc, f3 fatalLogFunc, - level string, t *testing.T) { - - tw := httptest.NewRecorder() - gw := httptest.NewRecorder() - kw := httptest.NewRecorder() - sw := httptest.NewRecorder() - - tl := ConsoleLogger(level) - tl.logger = gkl.NewJSONLogger(tw) - - sla := ConsoleLogger(level) - sla.logger = gkl.NewJSONLogger(sw) - - sl := &SyncLogger{Logger: sla} - gl := log.New(gw, "", 0) - kl := gkl.NewJSONLogger(kw) - - loggers := []interface{}{nil, tl, sl, gl, kl} - - // cover debug cases - for _, logger := range loggers { - - if f1 != nil { - f1(logger, "test trickster "+level, Pairs{"testKey": "testValue"}) - } - if f2 != nil { - f2(logger, "test-key", "test trickster "+level, Pairs{"testKey": "testValue"}) - } - if f3 != nil { - f3(logger, -1, "test trickster "+level, Pairs{"testKey": "testValue"}) - } - } - time.Sleep(time.Millisecond * 300) - - if tw.Body.String() == "" { - t.Error("expected non-empty string") - } - - if gw.Body.String() == "" { - t.Error("expected non-empty string") - } - - if kw.Body.String() == "" { - t.Error("expected non-empty string") - } - - if sw.Body.String() == "" { - t.Error("expected non-empty string") + t.Errorf("expected %s got %s", "warn", l.Level()) } } func TestStreamLogger(t *testing.T) { - w := httptest.NewRecorder() sl := StreamLogger(w, "ERROR") + sl.SetLogAsynchronous(false) sl.Error("test error", Pairs{"testKey": "testVal"}) if w.Body.String() == "" { t.Error("expected non-empty string") diff --git a/pkg/observability/tracing/registration/registration.go b/pkg/observability/tracing/registration/registration.go index 5e95ad6d4..39b75ca30 100644 --- a/pkg/observability/tracing/registration/registration.go +++ b/pkg/observability/tracing/registration/registration.go @@ -22,7 +22,7 @@ import ( "fmt" "github.com/trickstercache/trickster/v2/pkg/config" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" "github.com/trickstercache/trickster/v2/pkg/observability/tracing" "github.com/trickstercache/trickster/v2/pkg/observability/tracing/exporters/noop" "github.com/trickstercache/trickster/v2/pkg/observability/tracing/exporters/otlp" @@ -35,7 +35,8 @@ import ( // RegisterAll registers all Tracers in the provided configuration, and returns // their Flushers -func RegisterAll(cfg *config.Config, logger interface{}, isDryRun bool) (tracing.Tracers, error) { +func RegisterAll(cfg *config.Config, logger logging.Logger, + isDryRun bool) (tracing.Tracers, error) { if cfg == nil { return nil, errors.New("no config provided") } @@ -83,10 +84,11 @@ func RegisterAll(cfg *config.Config, logger interface{}, isDryRun bool) (tracing } // GetTracer returns a *Tracer based on the provided options -func GetTracer(options *options.Options, logger interface{}, isDryRun bool) (*tracing.Tracer, error) { +func GetTracer(options *options.Options, logger logging.Logger, + isDryRun bool) (*tracing.Tracer, error) { if options == nil { - tl.Info(logger, "nil tracing config, using noop tracer", tl.Pairs{}) + logger.Info("nil tracing config, using noop tracer", nil) return noop.New(options) } @@ -94,9 +96,8 @@ func GetTracer(options *options.Options, logger interface{}, isDryRun bool) (*tr if isDryRun { return } - tl.Info(logger, - "tracer registration", - tl.Pairs{ + logger.Info("tracer registration", + logging.Pairs{ "name": options.Name, "provider": options.Provider, "serviceName": options.ServiceName, diff --git a/pkg/observability/tracing/registration/registration_test.go b/pkg/observability/tracing/registration/registration_test.go index 6df8b38d2..85facf24a 100644 --- a/pkg/observability/tracing/registration/registration_test.go +++ b/pkg/observability/tracing/registration/registration_test.go @@ -20,14 +20,14 @@ import ( "testing" "github.com/trickstercache/trickster/v2/pkg/config" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" "github.com/trickstercache/trickster/v2/pkg/observability/tracing/options" ) func TestRegisterAll(t *testing.T) { // test nil config - f, err := RegisterAll(nil, tl.ConsoleLogger("error"), true) + f, err := RegisterAll(nil, logging.ConsoleLogger("error"), true) if err == nil { t.Error("expected error for no config provided") } @@ -36,7 +36,7 @@ func TestRegisterAll(t *testing.T) { } // test good config - f, err = RegisterAll(config.NewConfig(), tl.ConsoleLogger("error"), true) + f, err = RegisterAll(config.NewConfig(), logging.ConsoleLogger("error"), true) if err != nil { t.Error(err) } @@ -53,47 +53,47 @@ func TestRegisterAll(t *testing.T) { cfg.TracingConfigs["test3"] = tc cfg.Backends["default"].TracingConfigName = "test" - _, err = RegisterAll(cfg, tl.ConsoleLogger("error"), true) + _, err = RegisterAll(cfg, logging.ConsoleLogger("error"), true) if err != nil { t.Error(err) } tc.Provider = "otlp" tc.Endpoint = "http://example.com" - _, err = RegisterAll(cfg, tl.ConsoleLogger("error"), false) + _, err = RegisterAll(cfg, logging.ConsoleLogger("error"), false) if err != nil { t.Error(err) } tc.Provider = "stdout" - _, err = RegisterAll(cfg, tl.ConsoleLogger("error"), true) + _, err = RegisterAll(cfg, logging.ConsoleLogger("error"), true) if err != nil { t.Error(err) } tc.Provider = "zipkin" - _, err = RegisterAll(cfg, tl.ConsoleLogger("error"), true) + _, err = RegisterAll(cfg, logging.ConsoleLogger("error"), true) if err != nil { t.Error(err) } tc.Provider = "foo" - _, err = RegisterAll(cfg, tl.ConsoleLogger("error"), true) + _, err = RegisterAll(cfg, logging.ConsoleLogger("error"), true) if err == nil { t.Error("expected error for invalid provider") } // test empty implementation tc.Provider = "" - f, _ = RegisterAll(cfg, tl.ConsoleLogger("error"), true) + f, _ = RegisterAll(cfg, logging.ConsoleLogger("error"), true) if len(f) > 0 { t.Errorf("expected %d got %d", 0, len(f)) } tc.Provider = "none" cfg.Backends["default"].TracingConfigName = "test2" - _, err = RegisterAll(cfg, tl.ConsoleLogger("error"), true) + _, err = RegisterAll(cfg, logging.ConsoleLogger("error"), true) if err == nil { t.Error("expected error for invalid tracing config name") } @@ -102,7 +102,7 @@ func TestRegisterAll(t *testing.T) { temp := cfg.TracingConfigs cfg.TracingConfigs = nil // test nil tracing config - f, _ = RegisterAll(cfg, tl.ConsoleLogger("error"), true) + f, _ = RegisterAll(cfg, logging.ConsoleLogger("error"), true) if len(f) > 0 { t.Errorf("expected %d got %d", 0, len(f)) } @@ -110,7 +110,7 @@ func TestRegisterAll(t *testing.T) { // test nil backend options cfg.Backends = nil - _, err = RegisterAll(cfg, tl.ConsoleLogger("error"), true) + _, err = RegisterAll(cfg, logging.ConsoleLogger("error"), true) if err == nil { t.Error("expected error for invalid tracing implementation") } @@ -118,7 +118,7 @@ func TestRegisterAll(t *testing.T) { } func TestGetTracer(t *testing.T) { - tr, _ := GetTracer(nil, tl.ConsoleLogger("error"), true) + tr, _ := GetTracer(nil, logging.ConsoleLogger("error"), true) if tr != nil { t.Error("expected nil tracer") } diff --git a/pkg/parsing/run_state.go b/pkg/parsing/run_state.go index 5248f29a9..c9d156582 100644 --- a/pkg/parsing/run_state.go +++ b/pkg/parsing/run_state.go @@ -29,7 +29,7 @@ type RunState struct { err error ctx context.Context nextOverride StateFn - results map[string]interface{} + results map[string]any pos int cnt int } @@ -39,7 +39,7 @@ func NewRunState(ctx context.Context, tokens token.Tokens) *RunState { t := tokens.Compress() rs := &RunState{ ctx: ctx, - results: make(map[string]interface{}), + results: make(map[string]any), tokens: t, cnt: len(t), pos: -1, @@ -48,18 +48,18 @@ func NewRunState(ctx context.Context, tokens token.Tokens) *RunState { } // SetResultsCollection places a collection of results into the results map -func (rs *RunState) SetResultsCollection(collectionName string, val interface{}) { +func (rs *RunState) SetResultsCollection(collectionName string, val any) { rs.results[collectionName] = val } // GetResultsCollection retrieves a collection from the results map -func (rs *RunState) GetResultsCollection(collectionName string) (interface{}, bool) { +func (rs *RunState) GetResultsCollection(collectionName string) (any, bool) { v, ok := rs.results[collectionName] return v, ok } // Results returns the results objecxt from the RunState -func (rs *RunState) Results() map[string]interface{} { +func (rs *RunState) Results() map[string]any { return rs.results } diff --git a/pkg/proxy/context/resources.go b/pkg/proxy/context/resources.go index 7d4bdc17c..d6fc83878 100644 --- a/pkg/proxy/context/resources.go +++ b/pkg/proxy/context/resources.go @@ -22,7 +22,7 @@ import ( // WithResources returns a copy of the provided context that also includes the BackendOptions, // CachingConfig and PathConfig for the request -func WithResources(ctx context.Context, r interface{}) context.Context { +func WithResources(ctx context.Context, r any) context.Context { if r != nil { return context.WithValue(StartRewriterHops(ctx), resourcesKey, r) } @@ -30,6 +30,6 @@ func WithResources(ctx context.Context, r interface{}) context.Context { } // Resources returns the interface reference to the Request's resources -func Resources(ctx context.Context) interface{} { +func Resources(ctx context.Context) any { return ctx.Value(resourcesKey) } diff --git a/pkg/proxy/engines/access_logs.go b/pkg/proxy/engines/access_logs.go index df2fe62d5..d17dc03c0 100644 --- a/pkg/proxy/engines/access_logs.go +++ b/pkg/proxy/engines/access_logs.go @@ -19,13 +19,13 @@ package engines import ( "net/http" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" ) -func logUpstreamRequest(logger interface{}, backendName, backendProvider, handlerName, method, +func logUpstreamRequest(logger logging.Logger, backendName, backendProvider, handlerName, method, path, userAgent string, responseCode, size int, requestDuration float64) { - tl.Debug(logger, "upstream request", - tl.Pairs{ + logger.Debug("upstream request", + logging.Pairs{ "backendName": backendName, "backendProvider": backendProvider, "handlerName": handlerName, @@ -38,9 +38,9 @@ func logUpstreamRequest(logger interface{}, backendName, backendProvider, handle }) } -func logDownstreamRequest(logger interface{}, r *http.Request) { - tl.Debug(logger, "downtream request", - tl.Pairs{ +func logDownstreamRequest(logger logging.Logger, r *http.Request) { + logger.Debug("downtream request", + logging.Pairs{ "uri": r.RequestURI, "method": r.Method, "userAgent": r.UserAgent(), diff --git a/pkg/proxy/engines/access_logs_test.go b/pkg/proxy/engines/access_logs_test.go index c1cde0f2f..566182eb1 100644 --- a/pkg/proxy/engines/access_logs_test.go +++ b/pkg/proxy/engines/access_logs_test.go @@ -22,7 +22,7 @@ import ( "testing" "github.com/trickstercache/trickster/v2/pkg/config" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" tlo "github.com/trickstercache/trickster/v2/pkg/observability/logging/options" ) @@ -32,13 +32,14 @@ func TestLogUpstreamRequest(t *testing.T) { conf := config.NewConfig() conf.Main = &config.MainConfig{InstanceID: 0} conf.Logging = &tlo.Options{LogFile: fileName, LogLevel: "debug"} - log := &tl.SyncLogger{Logger: tl.New(conf)} - logUpstreamRequest(log, "testBackend", "testType", "testHandler", "testMethod", + logger := logging.New(conf) + logger.SetLogAsynchronous(false) + logUpstreamRequest(logger, "testBackend", "testType", "testHandler", "testMethod", "testPath", "testUserAgent", 200, 0, 1.0) if _, err := os.Stat(fileName); err != nil { t.Errorf(err.Error()) } - log.Close() + logger.Close() } func TestLogDownstreamRequest(t *testing.T) { @@ -47,16 +48,17 @@ func TestLogDownstreamRequest(t *testing.T) { conf := config.NewConfig() conf.Main = &config.MainConfig{InstanceID: 0} conf.Logging = &tlo.Options{LogFile: fileName, LogLevel: "debug"} - log := &tl.SyncLogger{Logger: tl.New(conf)} + logger := logging.New(conf) + logger.SetLogAsynchronous(false) r, err := http.NewRequest("get", "http://testBackend", nil) if err != nil { t.Error(err) } - logDownstreamRequest(log, r) + logDownstreamRequest(logger, r) if _, err := os.Stat(fileName); err != nil { t.Errorf(err.Error()) } - log.Close() + logger.Close() } diff --git a/pkg/proxy/engines/cache.go b/pkg/proxy/engines/cache.go index 35468ce6a..7c2370b19 100644 --- a/pkg/proxy/engines/cache.go +++ b/pkg/proxy/engines/cache.go @@ -29,6 +29,7 @@ import ( "github.com/trickstercache/trickster/v2/pkg/cache" "github.com/trickstercache/trickster/v2/pkg/cache/status" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" tspan "github.com/trickstercache/trickster/v2/pkg/observability/tracing/span" tc "github.com/trickstercache/trickster/v2/pkg/proxy/context" "github.com/trickstercache/trickster/v2/pkg/proxy/headers" @@ -48,14 +49,14 @@ type queryResult struct { err error } -func queryConcurrent(ctx context.Context, c cache.Cache, key string, cr chan<- *queryResult, done func()) *queryResult { +func queryConcurrent(_ context.Context, c cache.Cache, key string, cr chan<- *queryResult, done func()) *queryResult { if done != nil { defer done() } qr := &queryResult{queryKey: key, d: &HTTPDocument{}} if c.Configuration().Provider == "memory" { mc := c.(cache.MemoryCache) - var ifc interface{} + var ifc any ifc, qr.lookupStatus, qr.err = mc.RetrieveReference(key, true) if qr.err != nil || (qr.lookupStatus != status.LookupStatusHit) { @@ -321,7 +322,7 @@ func stripConditionalHeaders(h http.Header) { h.Del(headers.NameIfModifiedSince) } -func writeConcurrent(ctx context.Context, c cache.Cache, key string, d *HTTPDocument, +func writeConcurrent(_ context.Context, c cache.Cache, key string, d *HTTPDocument, compress bool, ttl time.Duration, cr chan<- error, done func()) { if done != nil { @@ -372,7 +373,7 @@ func writeConcurrent(ctx context.Context, c cache.Cache, key string, d *HTTPDocu // WriteCache writes an HTTPDocument to the cache func WriteCache(ctx context.Context, c cache.Cache, key string, d *HTTPDocument, - ttl time.Duration, compressTypes map[string]interface{}, marshal timeseries.MarshalerFunc) error { + ttl time.Duration, compressTypes map[string]any, marshal timeseries.MarshalerFunc) error { rsc := tc.Resources(ctx).(*request.Resources) @@ -442,7 +443,7 @@ func WriteCache(ctx context.Context, c cache.Cache, key string, d *HTTPDocument, close(cr) // Handle results for res := range cr { - if res != nil && err != nil { + if res != nil { err = res break } @@ -484,7 +485,7 @@ func WriteCache(ctx context.Context, c cache.Cache, key string, d *HTTPDocument, close(cr) // Handle results for res := range cr { - if res != nil && err != nil { + if res != nil { err = res break } @@ -528,7 +529,7 @@ func WriteCache(ctx context.Context, c cache.Cache, key string, d *HTTPDocument, // DocumentFromHTTPResponse returns an HTTPDocument from the provided // HTTP Response and Body func DocumentFromHTTPResponse(resp *http.Response, body []byte, - cp *CachingPolicy, logger interface{}) *HTTPDocument { + cp *CachingPolicy, logger logging.Logger) *HTTPDocument { d := &HTTPDocument{} d.StatusCode = resp.StatusCode d.Status = resp.Status diff --git a/pkg/proxy/engines/client_test.go b/pkg/proxy/engines/client_test.go index 537eb9e96..5d0b219ea 100644 --- a/pkg/proxy/engines/client_test.go +++ b/pkg/proxy/engines/client_test.go @@ -23,7 +23,6 @@ import ( "math" "net/http" "net/url" - "sort" "strconv" "strings" "time" @@ -37,7 +36,6 @@ import ( po "github.com/trickstercache/trickster/v2/pkg/proxy/paths/options" tst "github.com/trickstercache/trickster/v2/pkg/testutil/timeseries/model" "github.com/trickstercache/trickster/v2/pkg/timeseries" - "github.com/trickstercache/trickster/v2/pkg/timeseries/dataset" tt "github.com/trickstercache/trickster/v2/pkg/util/timeconv" ) @@ -357,83 +355,6 @@ func (c *TestClient) FastForwardRequest(r *http.Request) (*http.Request, error) return nr, nil } -// // VectorEnvelope represents a Vector response object from the Prometheus HTTP API -// type VectorEnvelope struct { -// Status string `json:"status"` -// Data VectorData `json:"data"` -// } - -// // VectorData represents the Data body of a Vector response object from the Prometheus HTTP API -// type VectorData struct { -// ResultType string `json:"resultType"` -// Result model.Vector `json:"result"` -// } - -// // MatrixEnvelope represents a Matrix response object from the Prometheus HTTP API -// type MatrixEnvelope struct { -// Status string `json:"status"` -// Data MatrixData `json:"data"` -// ExtentList timeseries.ExtentList `json:"extents,omitempty"` -// StepDuration time.Duration `json:"step,omitempty"` - -// timestamps map[time.Time]bool // tracks unique timestamps in the matrix data -// tslist times.Times -// isSorted bool // tracks if the matrix data is currently sorted -// isCounted bool // tracks if timestamps slice is up-to-date - -// timeRangeQuery *timeseries.TimeRangeQuery -// } - -// // MatrixData represents the Data body of a Matrix response object from the Prometheus HTTP API -// type MatrixData struct { -// ResultType string `json:"resultType"` -// Result model.Matrix `json:"result"` -// } - -func (c *TestClient) marshalTimeseriesWriter(ts timeseries.Timeseries, w io.Writer) error { - // Marshal the Envelope back to a json object for Cache Storage - if c.RangeCacheKey == "failkey" { - return fmt.Errorf("generic failure for testing purposes (key: %s)", c.RangeCacheKey) - } - - ds, ok := ts.(*dataset.DataSet) - if !ok { - return timeseries.ErrUnknownFormat - } - // With Prometheus we presume only one Result per Dataset - if len(ds.Results) != 1 { - return timeseries.ErrUnknownFormat - } - - w.Write([]byte(`{"status":"success","data":{"resultType":"matrix","result":[`)) // todo: always "success" ? - - seriesSep := "" - for _, s := range ds.Results[0].SeriesList { - w.Write([]byte(seriesSep + `{"metric":{`)) - sep := "" - for _, k := range s.Header.Tags.Keys() { - w.Write([]byte(fmt.Sprintf(`%s"%s":"%s"`, sep, k, s.Header.Tags[k]))) - sep = "," - } - w.Write([]byte(`},"values":[`)) - sep = "" - sort.Sort(s.Points) - for _, p := range s.Points { - w.Write([]byte(fmt.Sprintf(`%s[%s,"%s"]`, - sep, - strconv.FormatFloat(float64(p.Epoch)/1000000000, 'f', -1, 64), - p.Values[0]), - )) - sep = "," - } - w.Write([]byte("]}")) - seriesSep = "," - } - w.Write([]byte("]}}")) - return nil - -} - func (c *TestClient) testModeler() *timeseries.Modeler { m := tst.Modeler() mw := m.WireMarshalWriter diff --git a/pkg/proxy/engines/deltaproxycache.go b/pkg/proxy/engines/deltaproxycache.go index ad4f86b15..d3eeec7d5 100644 --- a/pkg/proxy/engines/deltaproxycache.go +++ b/pkg/proxy/engines/deltaproxycache.go @@ -32,7 +32,7 @@ import ( "github.com/trickstercache/trickster/v2/pkg/encoding/profile" "github.com/trickstercache/trickster/v2/pkg/encoding/providers" "github.com/trickstercache/trickster/v2/pkg/locks" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" "github.com/trickstercache/trickster/v2/pkg/observability/metrics" tspan "github.com/trickstercache/trickster/v2/pkg/observability/tracing/span" tctx "github.com/trickstercache/trickster/v2/pkg/proxy/context" @@ -75,7 +75,8 @@ func DeltaProxyCacheRequest(w http.ResponseWriter, r *http.Request, modeler *tim rsc.TSReqestOptions = rlo if err != nil { if canOPC { - tl.Debug(rsc.Logger, "could not parse time range query, using object proxy cache", tl.Pairs{"error": err.Error()}) + rsc.Logger.Debug("could not parse time range query, using object proxy cache", + logging.Pairs{"error": err.Error()}) rsc.AlternateCacheTTL = time.Second * o.FastForwardTTL ObjectProxyCacheRequest(w, r) return @@ -97,8 +98,8 @@ func DeltaProxyCacheRequest(w http.ResponseWriter, r *http.Request, modeler *tim if o.TimeseriesEvictionMethod == evictionmethods.EvictionMethodOldest { OldestRetainedTimestamp = now.Truncate(trq.Step).Add(-(trq.Step * o.TimeseriesRetention)) if trq.Extent.End.Before(OldestRetainedTimestamp) { - tl.Debug(pr.Logger, "timerange end is too old to consider caching", - tl.Pairs{"oldestRetainedTimestamp": OldestRetainedTimestamp, + pr.Logger.Debug("timerange end is too old to consider caching", + logging.Pairs{"oldestRetainedTimestamp": OldestRetainedTimestamp, "step": trq.Step, "retention": o.TimeseriesRetention}) DoProxy(w, r, true) return @@ -157,8 +158,8 @@ checkCache: cts = doc.timeseries } if err != nil { - tl.Error(pr.Logger, "cache object unmarshaling failed", - tl.Pairs{"key": key, "backendName": client.Name(), "detail": err.Error()}) + pr.Logger.Error("cache object unmarshaling failed", + logging.Pairs{"key": key, "backendName": client.Name(), "detail": err.Error()}) go cache.Remove(key) cts, doc, elapsed, err = fetchTimeseries(pr, trq, client, modeler) if err != nil { @@ -177,8 +178,8 @@ checkCache: tsc >= int64(o.TimeseriesRetentionFactor) { if trq.Extent.End.Before(el[0].Start) { pr.cacheLock.RRelease() - tl.Debug(pr.Logger, "timerange end is too old to consider caching", - tl.Pairs{"step": trq.Step, "retention": o.TimeseriesRetention}) + pr.Logger.Debug("timerange end is too old to consider caching", + logging.Pairs{"step": trq.Step, "retention": o.TimeseriesRetention}) DoProxy(w, r, true) return } @@ -292,8 +293,8 @@ checkCache: ffts, err = modeler.WireUnmarshalerReader(getDecoderReader(resp), trq) if err != nil { ffStatus = "err" - tl.Error(pr.Logger, "proxy object unmarshaling failed", - tl.Pairs{"body": string(body)}) + pr.Logger.Error("proxy object unmarshaling failed", + logging.Pairs{"body": string(body)}) return } ffts.SetTimeRangeQuery(trq) @@ -312,7 +313,7 @@ checkCache: // while fast forward fetching is occurring in a goroutine, this section will // fetch any uncached ranges in cases of partial hit or range miss - dpStatus := tl.Pairs{ + dpStatus := logging.Pairs{ "cacheKey": key, "cacheStatus": cacheStatus, "reqStart": trq.Extent.Start.Unix(), @@ -416,8 +417,8 @@ checkCache: if len(cts.Extents()) > 0 { doc.timeseries = cts if err := WriteCache(ctx, cache, key, doc, o.TimeseriesTTL, o.CompressibleTypes, modeler.CacheMarshaler); err != nil { - tl.Error(pr.Logger, "error writing object to cache", - tl.Pairs{ + pr.Logger.Error("error writing object to cache", + logging.Pairs{ "backendName": o.Name, "cacheName": cache.Configuration().Name, "cacheKey": key, @@ -473,8 +474,8 @@ checkCache: modeler.WireMarshalWriter(rts, rlo, sc, w) } -func logDeltaRoutine(logger interface{}, p tl.Pairs) { - tl.Debug(logger, "delta routine completed", p) +func logDeltaRoutine(logger logging.Logger, p logging.Pairs) { + logger.Debug("delta routine completed", p) } var dpcEncodingProfile = &profile.Profile{ @@ -605,8 +606,8 @@ func fetchExtents(el timeseries.ExtentList, rsc *request.Resources, h http.Heade if resp.StatusCode == http.StatusOK && len(body) > 0 { nts, ferr := wur(getDecoderReader(resp), rsc.TimeRangeQuery) if ferr != nil { - tl.Error(pr.Logger, "proxy object unmarshaling failed", - tl.Pairs{"detail": ferr.Error()}) + pr.Logger.Error("proxy object unmarshaling failed", + logging.Pairs{"detail": ferr.Error()}) appendLock.Lock() if err == nil { err = ferr @@ -635,8 +636,8 @@ func fetchExtents(el timeseries.ExtentList, rsc *request.Resources, h http.Heade if len(s) > 128 { s = s[:128] } - tl.Error(pr.Logger, "unexpected upstream response", - tl.Pairs{ + pr.Logger.Error("unexpected upstream response", + logging.Pairs{ "statusCode": resp.StatusCode, "clientRequestURL": pr.Request.URL.String(), "clientRequestMethod": pr.Request.Method, diff --git a/pkg/proxy/engines/deltaproxycache_test.go b/pkg/proxy/engines/deltaproxycache_test.go index 5b1cab26b..f5d6cba93 100644 --- a/pkg/proxy/engines/deltaproxycache_test.go +++ b/pkg/proxy/engines/deltaproxycache_test.go @@ -26,10 +26,11 @@ import ( mockprom "github.com/trickstercache/mockster/pkg/mocks/prometheus" "github.com/trickstercache/trickster/v2/pkg/backends" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" "github.com/trickstercache/trickster/v2/pkg/proxy/headers" "github.com/trickstercache/trickster/v2/pkg/proxy/request" - "github.com/trickstercache/trickster/v2/pkg/timeseries" tu "github.com/trickstercache/trickster/v2/pkg/testutil" + "github.com/trickstercache/trickster/v2/pkg/timeseries" ) // test queries @@ -54,6 +55,7 @@ func setupTestHarnessDPC() (*httptest.Server, *httptest.ResponseRecorder, *http. rsc := request.GetResources(r) rsc.BackendClient = client rsc.Tracer = tu.NewTestTracer() + rsc.Logger = logging.NoopLogger() pc := rsc.PathConfig if pc == nil { @@ -229,7 +231,7 @@ func TestDeltaProxyCacheRequestRemoveStale(t *testing.T) { } -// Will understand why this test is failing, and if it's due to an application or test defect, +// TODO: Will understand why this test is failing, and if it's due to an application or test defect, // Will commit to test issue fix in v1.2.0 or app defect fix in the next release of v1.1.x // func TestDeltaProxyCacheRequestRemoveStaleLRU(t *testing.T) { diff --git a/pkg/proxy/engines/document.go b/pkg/proxy/engines/document.go index 730558919..f65decb12 100644 --- a/pkg/proxy/engines/document.go +++ b/pkg/proxy/engines/document.go @@ -26,7 +26,7 @@ import ( "strings" "sync" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" txe "github.com/trickstercache/trickster/v2/pkg/proxy/errors" "github.com/trickstercache/trickster/v2/pkg/proxy/headers" "github.com/trickstercache/trickster/v2/pkg/proxy/ranges/byterange" @@ -206,7 +206,8 @@ func (d *HTTPDocument) LoadRangeParts() { } // ParsePartialContentBody parses a Partial Content response body into 0 or more discrete parts -func (d *HTTPDocument) ParsePartialContentBody(resp *http.Response, body []byte, logger interface{}) { +func (d *HTTPDocument) ParsePartialContentBody(resp *http.Response, + body []byte, logger logging.Logger) { ct := resp.Header.Get(headers.NameContentType) if cr := resp.Header.Get(headers.NameContentRange); cr != "" { @@ -249,7 +250,8 @@ func (d *HTTPDocument) ParsePartialContentBody(resp *http.Response, body []byte, d.RangeParts.Compress() d.Ranges = d.RangeParts.Ranges() } else { - tl.Error(logger, "unable to parse multipart range response body", tl.Pairs{"detail": err.Error}) + logger.Error("unable to parse multipart range response body", + logging.Pairs{"detail": err.Error}) } } else { if !strings.HasPrefix(ct, headers.ValueMultipartByteRanges) { diff --git a/pkg/proxy/engines/httpproxy.go b/pkg/proxy/engines/httpproxy.go index 0503dc67d..77eee4166 100644 --- a/pkg/proxy/engines/httpproxy.go +++ b/pkg/proxy/engines/httpproxy.go @@ -28,7 +28,7 @@ import ( "github.com/trickstercache/trickster/v2/pkg/cache/status" "github.com/trickstercache/trickster/v2/pkg/encoding/profile" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" "github.com/trickstercache/trickster/v2/pkg/observability/metrics" "github.com/trickstercache/trickster/v2/pkg/observability/tracing" tspan "github.com/trickstercache/trickster/v2/pkg/observability/tracing/span" @@ -124,11 +124,11 @@ func DoProxy(w io.Writer, r *http.Request, closeResponse bool) *http.Response { } elapsed = time.Since(start) - recordResults(r, "HTTPProxy", cacheStatusCode, resp.StatusCode, - r.URL.Path, "", elapsed.Seconds(), nil, resp.Header) if resp != nil && rsc != nil && (rsc.IsMergeMember || rsc.TSTransformer != nil) { rsc.Response = resp + recordResults(r, "HTTPProxy", cacheStatusCode, resp.StatusCode, + r.URL.Path, "", elapsed.Seconds(), nil, resp.Header) } return resp @@ -194,7 +194,7 @@ func PrepareFetchReader(r *http.Request) (io.ReadCloser, *http.Response, int64) othttptrace.Inject(ctx, r) } - ctx, doSpan := tspan.NewChildSpan(r.Context(), rsc.Tracer, "ProxyRequest") + _, doSpan := tspan.NewChildSpan(r.Context(), rsc.Tracer, "ProxyRequest") if doSpan != nil { defer doSpan.End() } @@ -204,8 +204,8 @@ func PrepareFetchReader(r *http.Request) (io.ReadCloser, *http.Response, int64) resp, err := o.HTTPClient.Do(r) if err != nil { - tl.Error(rsc.Logger, - "error downloading url", tl.Pairs{"url": r.URL.String(), "detail": err.Error()}) + rsc.Logger.Error("error downloading url", + logging.Pairs{"url": r.URL.String(), "detail": err.Error()}) // if there is an err and the response is nil, the server could not be reached // so make a 502 for the downstream response if resp == nil { @@ -252,9 +252,9 @@ func PrepareFetchReader(r *http.Request) (io.ReadCloser, *http.Response, int64) d, err := http.ParseTime(date) if err == nil { if offset := time.Since(d); time.Duration(math.Abs(float64(offset))) > time.Minute { - tl.WarnOnce(rsc.Logger, "clockoffset."+o.Name, + rsc.Logger.WarnOnce("clockoffset."+o.Name, ClockOffsetWarning, - tl.Pairs{ + logging.Pairs{ "backendName": o.Name, "tricksterTime": strconv.FormatInt(d.Add(offset).Unix(), 10), "originTime": strconv.FormatInt(d.Unix(), 10), diff --git a/pkg/proxy/engines/httpproxy_test.go b/pkg/proxy/engines/httpproxy_test.go index 14e3f08d6..bee63034f 100644 --- a/pkg/proxy/engines/httpproxy_test.go +++ b/pkg/proxy/engines/httpproxy_test.go @@ -25,7 +25,7 @@ import ( "time" "github.com/trickstercache/trickster/v2/pkg/config" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" tc "github.com/trickstercache/trickster/v2/pkg/proxy/context" "github.com/trickstercache/trickster/v2/pkg/proxy/forwarding" "github.com/trickstercache/trickster/v2/pkg/proxy/headers" @@ -34,7 +34,7 @@ import ( tu "github.com/trickstercache/trickster/v2/pkg/testutil" ) -var testLogger = tl.ConsoleLogger("error") +var testLogger = logging.ConsoleLogger("warn") func TestDoProxy(t *testing.T) { @@ -153,7 +153,8 @@ func TestClockOffsetWarning(t *testing.T) { w := httptest.NewRecorder() r := httptest.NewRequest("GET", s.URL, nil) r = r.WithContext(tc.WithResources(r.Context(), - request.NewResources(o, pc, nil, nil, nil, tu.NewTestTracer(), testLogger))) + request.NewResources(o, pc, nil, nil, nil, tu.NewTestTracer(), + testLogger))) if testLogger.HasWarnedOnce("clockoffset.default") { t.Errorf("expected %t got %t", false, true) diff --git a/pkg/proxy/engines/key.go b/pkg/proxy/engines/key.go index dbac3fb07..ee2d59807 100644 --- a/pkg/proxy/engines/key.go +++ b/pkg/proxy/engines/key.go @@ -115,6 +115,7 @@ func (pr *proxyRequest) DeriveCacheKey(extra string) string { } } } + // TODO: this value of r does not appear to be used r = request.SetBody(r, b) } diff --git a/pkg/proxy/engines/key_test.go b/pkg/proxy/engines/key_test.go index e58603654..de7801493 100644 --- a/pkg/proxy/engines/key_test.go +++ b/pkg/proxy/engines/key_test.go @@ -28,7 +28,7 @@ import ( "testing" bo "github.com/trickstercache/trickster/v2/pkg/backends/options" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" ct "github.com/trickstercache/trickster/v2/pkg/proxy/context" "github.com/trickstercache/trickster/v2/pkg/proxy/headers" po "github.com/trickstercache/trickster/v2/pkg/proxy/paths/options" @@ -129,7 +129,8 @@ func TestDeriveCacheKey(t *testing.T) { } newResources := func() *request.Resources { - return request.NewResources(cfg, cfg.Paths["root"], nil, nil, nil, nil, tl.ConsoleLogger("error")) + return request.NewResources(cfg, cfg.Paths["root"], nil, nil, nil, + nil, logging.ConsoleLogger("error")) } tr := httptest.NewRequest("GET", "http://127.0.0.1/?query=12345&start=0&end=0&step=300&time=0", nil) @@ -228,7 +229,7 @@ func TestDeriveCacheKeyAuthHeader(t *testing.T) { tr := httptest.NewRequest("GET", "http://127.0.0.1/?query=12345&start=0&end=0&step=300&time=0", nil) tr = tr.WithContext(ct.WithResources(context.Background(), request.NewResources(client.Configuration(), client.Configuration().Paths["root"], - nil, nil, nil, nil, tl.ConsoleLogger("error")))) + nil, nil, nil, nil, logging.ConsoleLogger("error")))) tr.Header.Add("Authorization", "test") tr.Header.Add("X-Test-Header", "test2") @@ -260,7 +261,8 @@ func TestDeriveCacheKeyNoPathConfig(t *testing.T) { tr := httptest.NewRequest("GET", "http://127.0.0.1/?query=12345&start=0&end=0&step=300&time=0", nil) tr = tr.WithContext(ct.WithResources(context.Background(), - request.NewResources(client.Configuration(), nil, nil, nil, nil, nil, tl.ConsoleLogger("error")))) + request.NewResources(client.Configuration(), nil, nil, nil, nil, nil, + logging.ConsoleLogger("error")))) pr := newProxyRequest(tr, nil) ck := pr.DeriveCacheKey("extra") diff --git a/pkg/proxy/engines/objectproxycache.go b/pkg/proxy/engines/objectproxycache.go index abf119569..05631970a 100644 --- a/pkg/proxy/engines/objectproxycache.go +++ b/pkg/proxy/engines/objectproxycache.go @@ -25,7 +25,7 @@ import ( "github.com/trickstercache/trickster/v2/pkg/cache" "github.com/trickstercache/trickster/v2/pkg/cache/status" "github.com/trickstercache/trickster/v2/pkg/encoding/profile" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" tspan "github.com/trickstercache/trickster/v2/pkg/observability/tracing/span" "github.com/trickstercache/trickster/v2/pkg/proxy/errors" "github.com/trickstercache/trickster/v2/pkg/proxy/forwarding" @@ -435,12 +435,13 @@ func fetchViaObjectProxyCache(w io.Writer, r *http.Request) (*http.Response, sta if f, ok := cacheResponseHandlers[pr.cacheStatus]; ok { f(pr) } else { - tl.Warn(pr.Logger, - "unhandled cache lookup response", tl.Pairs{"lookupStatus": pr.cacheStatus}) + pr.Logger.Warn("unhandled cache lookup response", + logging.Pairs{"lookupStatus": pr.cacheStatus}) return nil, status.LookupStatusProxyOnly } } else { - tl.Error(pr.Logger, "cache lookup error", tl.Pairs{"detail": err.Error()}) + pr.Logger.Error("cache lookup error", + logging.Pairs{"detail": err.Error()}) pr.cacheDocument = nil pr.cacheStatus = status.LookupStatusKeyMiss handleCacheKeyMiss(pr) diff --git a/pkg/proxy/engines/proxy_request.go b/pkg/proxy/engines/proxy_request.go index 6a37c5b7e..556016901 100644 --- a/pkg/proxy/engines/proxy_request.go +++ b/pkg/proxy/engines/proxy_request.go @@ -26,7 +26,7 @@ import ( "github.com/trickstercache/trickster/v2/pkg/cache/status" "github.com/trickstercache/trickster/v2/pkg/locks" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" tspan "github.com/trickstercache/trickster/v2/pkg/observability/tracing/span" tctx "github.com/trickstercache/trickster/v2/pkg/proxy/context" "github.com/trickstercache/trickster/v2/pkg/proxy/headers" @@ -80,7 +80,7 @@ type proxyRequest struct { collapsedForwarder ProgressiveCollapseForwarder cachingPolicy *CachingPolicy - Logger interface{} + Logger logging.Logger isPCF bool writeToCache bool hasWriteLock bool @@ -168,8 +168,8 @@ func (pr *proxyRequest) Fetch() ([]byte, *http.Response, time.Duration) { resp.Body = io.NopCloser(bytes.NewReader(body)) } if err != nil { - tl.Error(pr.Logger, "error reading body from http response", - tl.Pairs{"url": pr.URL.String(), "detail": err.Error()}) + pr.Logger.Error("error reading body from http response", + logging.Pairs{"url": pr.URL.String(), "detail": err.Error()}) return []byte{}, resp, 0 } diff --git a/pkg/proxy/engines/proxy_request_test.go b/pkg/proxy/engines/proxy_request_test.go index b3b7cefc8..328571350 100644 --- a/pkg/proxy/engines/proxy_request_test.go +++ b/pkg/proxy/engines/proxy_request_test.go @@ -27,7 +27,7 @@ import ( cr "github.com/trickstercache/trickster/v2/pkg/cache/registration" "github.com/trickstercache/trickster/v2/pkg/cache/status" "github.com/trickstercache/trickster/v2/pkg/config" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" "github.com/trickstercache/trickster/v2/pkg/proxy/headers" "github.com/trickstercache/trickster/v2/pkg/proxy/ranges/byterange" "github.com/trickstercache/trickster/v2/pkg/proxy/request" @@ -49,7 +49,8 @@ func TestParseRequestRanges(t *testing.T) { r.Header.Set(headers.NameRange, "bytes=0-10") o := &bo.Options{MultipartRangesDisabled: true} - r = request.SetResources(r, request.NewResources(o, nil, nil, nil, nil, nil, tl.ConsoleLogger("error"))) + r = request.SetResources(r, request.NewResources(o, nil, nil, nil, nil, + nil, logging.ConsoleLogger("error"))) pr := proxyRequest{ Request: r, @@ -137,7 +138,7 @@ func TestDetermineCacheability(t *testing.T) { r, _ := http.NewRequest(http.MethodGet, "http://127.0.0.1", nil) r = request.SetResources(r, request.NewResources(nil, nil, cache.Configuration(), - cache, nil, nil, tl.ConsoleLogger("error"))) + cache, nil, nil, logging.ConsoleLogger("error"))) pr := proxyRequest{ Request: r, @@ -185,7 +186,8 @@ func TestPrepareResponse(t *testing.T) { r.Header.Set(headers.NameRange, "bytes=0-10") o := &bo.Options{} - r = request.SetResources(r, request.NewResources(o, nil, nil, nil, nil, nil, tl.ConsoleLogger("error"))) + r = request.SetResources(r, request.NewResources(o, nil, nil, nil, nil, + nil, logging.ConsoleLogger("error"))) pr := proxyRequest{ Request: r, @@ -255,7 +257,8 @@ func TestPrepareRevalidationRequest(t *testing.T) { r.Header.Set(headers.NameRange, "bytes=0-10,12-20") o := &bo.Options{DearticulateUpstreamRanges: true} - r = request.SetResources(r, request.NewResources(o, nil, nil, nil, nil, nil, tl.ConsoleLogger("error"))) + r = request.SetResources(r, request.NewResources(o, nil, nil, nil, nil, + nil, logging.ConsoleLogger("error"))) pr := proxyRequest{ Request: r, @@ -283,7 +286,8 @@ func TestPrepareRevalidationRequestNoRange(t *testing.T) { r.Header.Set(headers.NameRange, "bytes=0-10,12-20") o := &bo.Options{DearticulateUpstreamRanges: true} - r = request.SetResources(r, request.NewResources(o, nil, nil, nil, nil, nil, tl.ConsoleLogger("error"))) + r = request.SetResources(r, request.NewResources(o, nil, nil, nil, nil, + nil, logging.ConsoleLogger("error"))) pr := proxyRequest{ Request: r, @@ -310,7 +314,8 @@ func TestPrepareUpstreamRequests(t *testing.T) { r.Header.Set(headers.NameRange, "bytes=0-10,12-20") o := &bo.Options{DearticulateUpstreamRanges: true} - r = request.SetResources(r, request.NewResources(o, nil, nil, nil, nil, nil, tl.ConsoleLogger("error"))) + r = request.SetResources(r, request.NewResources(o, nil, nil, nil, nil, + nil, logging.ConsoleLogger("error"))) pr := proxyRequest{ Request: r, diff --git a/pkg/proxy/engines/revalidation_status.go b/pkg/proxy/engines/revalidation_status.go index d0454c2ce..a866583ee 100644 --- a/pkg/proxy/engines/revalidation_status.go +++ b/pkg/proxy/engines/revalidation_status.go @@ -38,14 +38,6 @@ const ( RevalStatusFailed ) -var revalidationStatusNames = map[string]RevalidationStatus{ - "none": RevalStatusNone, - "revalidating": RevalStatusInProgress, - "revalidated": RevalStatusOK, - "failed": RevalStatusFailed, - "local": RevalStatusLocal, -} - var revalidationStatusValues = map[RevalidationStatus]string{ RevalStatusNone: "none", RevalStatusInProgress: "revalidating", diff --git a/pkg/proxy/handlers/local_test.go b/pkg/proxy/handlers/local_test.go index 661e3a5d4..f0e200f16 100644 --- a/pkg/proxy/handlers/local_test.go +++ b/pkg/proxy/handlers/local_test.go @@ -22,7 +22,7 @@ import ( "testing" "github.com/trickstercache/trickster/v2/pkg/config" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" tc "github.com/trickstercache/trickster/v2/pkg/proxy/context" "github.com/trickstercache/trickster/v2/pkg/proxy/headers" po "github.com/trickstercache/trickster/v2/pkg/proxy/paths/options" @@ -52,7 +52,8 @@ func TestHandleLocalResponse(t *testing.T) { } r = r.WithContext(tc.WithResources(r.Context(), - request.NewResources(nil, pc, nil, nil, nil, nil, tl.ConsoleLogger("error")))) + request.NewResources(nil, pc, nil, nil, nil, nil, + logging.ConsoleLogger("error")))) HandleLocalResponse(w, r) resp := w.Result() @@ -102,7 +103,7 @@ func TestHandleLocalResponseBadResponseCode(t *testing.T) { } r = r.WithContext(tc.WithResources(r.Context(), - request.NewResources(nil, pc, nil, nil, nil, nil, tl.ConsoleLogger("error")))) + request.NewResources(nil, pc, nil, nil, nil, nil, logging.ConsoleLogger("error")))) HandleLocalResponse(w, r) resp := w.Result() @@ -139,7 +140,7 @@ func TestHandleLocalResponseNoPathConfig(t *testing.T) { r := httptest.NewRequest("GET", "http://0/trickster/", nil) r = r.WithContext(tc.WithResources(r.Context(), - request.NewResources(nil, nil, nil, nil, nil, nil, tl.ConsoleLogger("error")))) + request.NewResources(nil, nil, nil, nil, nil, nil, logging.ConsoleLogger("error")))) HandleLocalResponse(w, r) resp := w.Result() diff --git a/pkg/proxy/handlers/purge.go b/pkg/proxy/handlers/purge.go index 15491671e..dc9e28638 100644 --- a/pkg/proxy/handlers/purge.go +++ b/pkg/proxy/handlers/purge.go @@ -69,14 +69,15 @@ func PurgePathHandlerFunc(conf *config.Config, from *backends.Backends) func(htt purgeFrom := req.URL.Query().Get("backend") purgePath := req.URL.Query().Get("path") if purgeFrom == "" || purgePath == "" { - logging.Warn(rsc.Logger, "failed to get backend/path args", nil) + rsc.Logger.Warn("failed to get backend/path args", nil) w.Header().Set(headers.NameContentType, headers.ValueTextPlain) w.Header().Set(headers.NameCacheControl, headers.ValueNoCache) w.WriteHeader(http.StatusBadRequest) w.Write([]byte("Usage: " + config.DefaultPurgePathHandlerPath + "?backend={backend}&path={path}")) return } - logging.Debug(rsc.Logger, "purging cache item", logging.Pairs{"backend": purgeFrom, "path": purgePath}) + rsc.Logger.Debug("purging cache item", + logging.Pairs{"backend": purgeFrom, "path": purgePath}) fromBackend := from.Get(purgeFrom) if fromBackend == nil { w.Header().Set(headers.NameContentType, headers.ValueTextPlain) diff --git a/pkg/proxy/handlers/reload.go b/pkg/proxy/handlers/reload.go index d527ba847..8bf60be30 100644 --- a/pkg/proxy/handlers/reload.go +++ b/pkg/proxy/handlers/reload.go @@ -23,22 +23,23 @@ import ( "github.com/trickstercache/trickster/v2/pkg/cache" "github.com/trickstercache/trickster/v2/pkg/config" "github.com/trickstercache/trickster/v2/pkg/config/reload" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" "github.com/trickstercache/trickster/v2/pkg/proxy/headers" ) // ReloadHandleFunc will reload the running configuration if it has changed func ReloadHandleFunc(f reload.ReloaderFunc, conf *config.Config, wg *sync.WaitGroup, - log *tl.Logger, caches map[string]cache.Cache, + logger logging.Logger, caches map[string]cache.Cache, args []string) func(http.ResponseWriter, *http.Request) { return func(w http.ResponseWriter, r *http.Request) { if conf != nil { conf.Main.ReloaderLock.Lock() defer conf.Main.ReloaderLock.Unlock() if conf.IsStale() { - tl.Warn(log, - "configuration reload starting now", tl.Pairs{"source": "reloadEndpoint"}) - err := f(conf, wg, log, caches, args, nil) + logger.Warn( + "configuration reload starting now", + logging.Pairs{"source": "reloadEndpoint"}) + err := f(conf, wg, logger, caches, args, nil) if err == nil { w.Header().Set(headers.NameContentType, headers.ValueTextPlain) w.Header().Set(headers.NameCacheControl, headers.ValueNoCache) diff --git a/pkg/proxy/handlers/reload_test.go b/pkg/proxy/handlers/reload_test.go index d21f7fddc..ac311213e 100644 --- a/pkg/proxy/handlers/reload_test.go +++ b/pkg/proxy/handlers/reload_test.go @@ -26,12 +26,13 @@ import ( "github.com/trickstercache/trickster/v2/pkg/cache" "github.com/trickstercache/trickster/v2/pkg/config" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging/level" ) func TestReloadHandleFunc(t *testing.T) { - var emptyFunc = func(*config.Config, *sync.WaitGroup, *tl.Logger, + var emptyFunc = func(*config.Config, *sync.WaitGroup, logging.Logger, map[string]cache.Cache, []string, func()) error { return nil } @@ -50,7 +51,7 @@ func TestReloadHandleFunc(t *testing.T) { cfg, _, _ := config.Load("testing", "testing", []string{"-config", testFile}) cfg.ReloadConfig.RateLimitMS = 0 - log := tl.ConsoleLogger("info") + log := logging.ConsoleLogger(level.Info) w := httptest.NewRecorder() r, _ := http.NewRequest("GET", "/", nil) diff --git a/pkg/proxy/listener/listener.go b/pkg/proxy/listener/listener.go index f1b760168..aaa7916a2 100644 --- a/pkg/proxy/listener/listener.go +++ b/pkg/proxy/listener/listener.go @@ -26,7 +26,7 @@ import ( "sync" "time" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" "github.com/trickstercache/trickster/v2/pkg/observability/metrics" "github.com/trickstercache/trickster/v2/pkg/observability/tracing" "github.com/trickstercache/trickster/v2/pkg/proxy/errors" @@ -117,7 +117,8 @@ func NewListenerGroup() *ListenerGroup { // connections (with operates with sampling through scrapes), and a set of // counter metrics for connections accepted, rejected and closed. func NewListener(listenAddress string, listenPort, connectionsLimit int, - tlsConfig *tls.Config, drainTimeout time.Duration, logger interface{}) (net.Listener, error) { + tlsConfig *tls.Config, drainTimeout time.Duration, + logger logging.Logger) (net.Listener, error) { var listener net.Listener var err error @@ -140,7 +141,7 @@ func NewListener(listenAddress string, listenPort, connectionsLimit int, metrics.ProxyMaxConnections.Set(float64(connectionsLimit)) } - tl.Debug(logger, "starting proxy listener", tl.Pairs{ + logger.Debug("starting proxy listener", logging.Pairs{ "connectionsLimit": connectionsLimit, "scheme": listenerType, "address": listenAddress, @@ -165,7 +166,7 @@ func (lg *ListenerGroup) Get(name string) *Listener { // StartListener starts a new HTTP listener and adds it to the listener group func (lg *ListenerGroup) StartListener(listenerName, address string, port int, connectionsLimit int, tlsConfig *tls.Config, router http.Handler, wg *sync.WaitGroup, tracers tracing.Tracers, - f func(), drainTimeout time.Duration, logger interface{}) error { + f func(), drainTimeout time.Duration, logger logging.Logger) error { if wg != nil { defer wg.Done() } @@ -182,15 +183,15 @@ func (lg *ListenerGroup) StartListener(listenerName, address string, port int, c var err error l.Listener, err = NewListener(address, port, connectionsLimit, tlsConfig, drainTimeout, logger) if err != nil { - tl.ErrorSynchronous(logger, - "http listener startup failed", tl.Pairs{"name": listenerName, "detail": err}) + logger.ErrorSynchronous( + "http listener startup failed", logging.Pairs{"listenerName": listenerName, "detail": err}) if f != nil { f() } return err } - tl.Info(logger, "http listener starting", - tl.Pairs{"name": listenerName, "port": port, "address": address}) + logger.Info("http listener starting", + logging.Pairs{"listenerName": listenerName, "port": port, "address": address}) lg.listenersLock.Lock() lg.members[listenerName] = l @@ -207,8 +208,8 @@ func (lg *ListenerGroup) StartListener(listenerName, address string, port int, c l.server = svr err = svr.Serve(l) if err != nil { - tl.ErrorSynchronous(logger, - "https listener stopping", tl.Pairs{"name": listenerName, "detail": err}) + logger.ErrorSynchronous( + "https listener stopping", logging.Pairs{"listenerName": listenerName, "detail": err}) if l.exitOnError { os.Exit(1) } @@ -222,8 +223,8 @@ func (lg *ListenerGroup) StartListener(listenerName, address string, port int, c l.server = svr err = svr.Serve(l) if err != nil { - tl.ErrorSynchronous(logger, - "http listener stopping", tl.Pairs{"name": listenerName, "detail": err}) + logger.ErrorSynchronous("http listener stopping", + logging.Pairs{"listenerName": listenerName, "detail": err}) if l.exitOnError { os.Exit(1) } @@ -231,14 +232,15 @@ func (lg *ListenerGroup) StartListener(listenerName, address string, port int, c return err } -func handleTracerShutdowns(tracers tracing.Tracers, logger interface{}) { +func handleTracerShutdowns(tracers tracing.Tracers, logger logging.Logger) { for _, v := range tracers { if v == nil || v.ShutdownFunc == nil { continue } err := v.ShutdownFunc(context.Background()) if err != nil { - tl.Error(logger, "tracer shutdown failed", tl.Pairs{"detail": err.Error()}) + logger.Error("tracer shutdown failed", + logging.Pairs{"detail": err.Error()}) } } } @@ -246,7 +248,7 @@ func handleTracerShutdowns(tracers tracing.Tracers, logger interface{}) { // StartListenerRouter starts a new HTTP listener with a new router, and adds it to the listener group func (lg *ListenerGroup) StartListenerRouter(listenerName, address string, port int, connectionsLimit int, tlsConfig *tls.Config, path string, handler http.Handler, wg *sync.WaitGroup, - tracers tracing.Tracers, f func(), drainTimeout time.Duration, logger interface{}) error { + tracers tracing.Tracers, f func(), drainTimeout time.Duration, logger logging.Logger) error { router := http.NewServeMux() router.Handle(path, handler) return lg.StartListener(listenerName, address, port, connectionsLimit, @@ -260,7 +262,7 @@ func (lg *ListenerGroup) DrainAndClose(listenerName string, drainWait time.Durat l.exitOnError = false delete(lg.members, listenerName) lg.listenersLock.Unlock() - if l == nil || l.Listener == nil { + if l.Listener == nil { return errors.ErrNilListener } ctx := context.Background() diff --git a/pkg/proxy/listener/listener_test.go b/pkg/proxy/listener/listener_test.go index b935ff591..c27af3e74 100644 --- a/pkg/proxy/listener/listener_test.go +++ b/pkg/proxy/listener/listener_test.go @@ -30,7 +30,7 @@ import ( "time" "github.com/trickstercache/trickster/v2/pkg/config" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" "github.com/trickstercache/trickster/v2/pkg/observability/tracing" "github.com/trickstercache/trickster/v2/pkg/observability/tracing/exporters/stdout" "github.com/trickstercache/trickster/v2/pkg/proxy/errors" @@ -61,7 +61,8 @@ func TestListeners(t *testing.T) { } err = testLG.StartListener("httpListener", - "", 0, 20, tc, http.NewServeMux(), wg, trs, nil, 0, tl.ConsoleLogger("info")) + "", 0, 20, tc, http.NewServeMux(), wg, trs, nil, 0, + logging.ConsoleLogger("info")) }() time.Sleep(time.Millisecond * 300) @@ -76,7 +77,7 @@ func TestListeners(t *testing.T) { go func() { err = testLG.StartListenerRouter("httpListener2", "", 0, 20, nil, "/", http.HandlerFunc(ph.HandleLocalResponse), wg, - nil, nil, 0, tl.ConsoleLogger("info")) + nil, nil, 0, logging.ConsoleLogger("info")) }() time.Sleep(time.Millisecond * 300) l = testLG.members["httpListener2"] @@ -88,7 +89,7 @@ func TestListeners(t *testing.T) { wg.Add(1) err = testLG.StartListener("testBadPort", - "", -31, 20, nil, http.NewServeMux(), wg, trs, nil, 0, tl.ConsoleLogger("info")) + "", -31, 20, nil, http.NewServeMux(), wg, trs, nil, 0, logging.ConsoleLogger("info")) if err == nil { t.Error("expected invalid port error") } @@ -107,7 +108,7 @@ func TestUpdateRouter(t *testing.T) { func TestNewListenerErr(t *testing.T) { config.NewConfig() - l, err := NewListener("-", 0, 0, nil, 0, tl.ConsoleLogger("error")) + l, err := NewListener("-", 0, 0, nil, 0, logging.ConsoleLogger("error")) if err == nil { l.Close() t.Errorf("expected error: %s", `listen tcp: lookup -: no such host`) @@ -119,7 +120,7 @@ func TestListenerAccept(t *testing.T) { var err error go func() { err = testLG.StartListener("httpListener", - "", 0, 20, nil, http.NewServeMux(), nil, nil, nil, 0, tl.ConsoleLogger("info")) + "", 0, 20, nil, http.NewServeMux(), nil, nil, nil, 0, logging.ConsoleLogger("info")) }() time.Sleep(time.Millisecond * 500) if err != nil { @@ -159,7 +160,7 @@ func TestNewListenerTLS(t *testing.T) { t.Error(err) } - l, err := NewListener("", 0, 0, tlsConfig, 0, tl.ConsoleLogger("error")) + l, err := NewListener("", 0, 0, tlsConfig, 0, logging.ConsoleLogger("error")) if err != nil { t.Error(err) } else { @@ -216,7 +217,7 @@ func TestListenerConnectionLimitWorks(t *testing.T) { for _, tc := range tt { t.Run(tc.Name, func(t *testing.T) { - l, err := NewListener("", tc.ListenPort, tc.ConnectionsLimit, nil, 0, tl.ConsoleLogger("error")) + l, err := NewListener("", tc.ListenPort, tc.ConnectionsLimit, nil, 0, logging.ConsoleLogger("error")) if err != nil { t.Fatal(err) } else { diff --git a/pkg/proxy/request/resources.go b/pkg/proxy/request/resources.go index 82a7a94f8..ce3f93fe3 100644 --- a/pkg/proxy/request/resources.go +++ b/pkg/proxy/request/resources.go @@ -24,6 +24,7 @@ import ( bo "github.com/trickstercache/trickster/v2/pkg/backends/options" "github.com/trickstercache/trickster/v2/pkg/cache" co "github.com/trickstercache/trickster/v2/pkg/cache/options" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" "github.com/trickstercache/trickster/v2/pkg/observability/tracing" tctx "github.com/trickstercache/trickster/v2/pkg/proxy/context" po "github.com/trickstercache/trickster/v2/pkg/proxy/paths/options" @@ -42,10 +43,10 @@ type Resources struct { AlternateCacheTTL time.Duration TimeRangeQuery *timeseries.TimeRangeQuery Tracer *tracing.Tracer - Logger interface{} + Logger logging.Logger IsMergeMember bool ResponseBytes []byte - ResponseMergeFunc interface{} + ResponseMergeFunc any TSUnmarshaler timeseries.UnmarshalerFunc TSMarshaler timeseries.MarshalWriterFunc TSTransformer func(timeseries.Timeseries) @@ -81,7 +82,7 @@ func (r *Resources) Clone() *Resources { // NewResources returns a new Resources collection based on the provided inputs func NewResources(oo *bo.Options, po *po.Options, co *co.Options, c cache.Cache, client backends.Backend, t *tracing.Tracer, - logger interface{}) *Resources { + logger logging.Logger) *Resources { return &Resources{ BackendOptions: oo, PathConfig: po, diff --git a/pkg/proxy/request/resources_test.go b/pkg/proxy/request/resources_test.go index e2fa32fa4..bb40dfd44 100644 --- a/pkg/proxy/request/resources_test.go +++ b/pkg/proxy/request/resources_test.go @@ -22,12 +22,12 @@ import ( "testing" "time" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" tc "github.com/trickstercache/trickster/v2/pkg/proxy/context" ) func TestNewAndCloneResources(t *testing.T) { - r := NewResources(nil, nil, nil, nil, nil, nil, tl.ConsoleLogger("error")) + r := NewResources(nil, nil, nil, nil, nil, nil, logging.ConsoleLogger("error")) r.AlternateCacheTTL = time.Duration(1) * time.Second r2 := r.Clone() if r2.AlternateCacheTTL != r.AlternateCacheTTL { @@ -42,7 +42,7 @@ func TestGetAndSetResources(t *testing.T) { t.Error("expected nil reference") } - r = NewResources(nil, nil, nil, nil, nil, nil, tl.ConsoleLogger("error")) + r = NewResources(nil, nil, nil, nil, nil, nil, logging.ConsoleLogger("error")) r.AlternateCacheTTL = time.Duration(1) * time.Second req, _ := http.NewRequest(http.MethodGet, "http://127.0.0.1/", nil) ctx := context.Background() @@ -69,13 +69,13 @@ func TestGetAndSetResources(t *testing.T) { } func TestMergeResources(t *testing.T) { - r1 := NewResources(nil, nil, nil, nil, nil, nil, tl.ConsoleLogger("error")) + r1 := NewResources(nil, nil, nil, nil, nil, nil, logging.ConsoleLogger("error")) r1.NoLock = true r1.Merge(nil) if !r1.NoLock { t.Errorf("nil merge shouldn't set anything in subject resources") } - r2 := NewResources(nil, nil, nil, nil, nil, nil, tl.ConsoleLogger("error")) + r2 := NewResources(nil, nil, nil, nil, nil, nil, logging.ConsoleLogger("error")) r1.Merge(r2) if r1.NoLock { t.Errorf("merge should override subject resources") diff --git a/pkg/routing/routing.go b/pkg/routing/routing.go index 038487ca3..9d442d55e 100644 --- a/pkg/routing/routing.go +++ b/pkg/routing/routing.go @@ -34,7 +34,7 @@ import ( "github.com/trickstercache/trickster/v2/pkg/cache" "github.com/trickstercache/trickster/v2/pkg/config" encoding "github.com/trickstercache/trickster/v2/pkg/encoding/handler" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" "github.com/trickstercache/trickster/v2/pkg/observability/tracing" "github.com/trickstercache/trickster/v2/pkg/proxy/handlers/health" "github.com/trickstercache/trickster/v2/pkg/proxy/methods" @@ -47,9 +47,8 @@ import ( ) // RegisterPprofRoutes will register the Pprof Debugging endpoints to the provided router -func RegisterPprofRoutes(routerName string, r router.Router, logger interface{}) { - tl.Info(logger, - "registering pprof /debug routes", tl.Pairs{"routerName": routerName}) +func RegisterPprofRoutes(routerName string, r router.Router, logger logging.Logger) { + logger.Info("registering pprof /debug routes", logging.Pairs{"routerName": routerName}) r.RegisterRoute("/debug/pprof/", nil, nil, false, http.HandlerFunc(pprof.Index)) r.RegisterRoute("/debug/pprof/cmdline", nil, nil, @@ -66,7 +65,7 @@ func RegisterPprofRoutes(routerName string, r router.Router, logger interface{}) // registers the routes for the configured backends func RegisterProxyRoutes(conf *config.Config, r router.Router, metricsRouter router.Router, caches map[string]cache.Cache, - tracers tracing.Tracers, logger interface{}, + tracers tracing.Tracers, logger logging.Logger, dryRun bool) (backends.Backends, error) { // a fake "top-level" backend representing the main frontend, so rules can route @@ -95,7 +94,7 @@ func RegisterProxyRoutes(conf *config.Config, r router.Router, fmt.Errorf("only one backend can be marked as default. Found both %s and %s", defaultBackend, k) } - tl.Debug(logger, "default backend identified", tl.Pairs{"name": k}) + logger.Debug("default backend identified", logging.Pairs{"name": k}) defaultBackend = k cdo = o continue @@ -159,7 +158,7 @@ func RegisterHealthHandler(router router.Router, path string, func registerBackendRoutes(r router.Router, metricsRouter router.Router, conf *config.Config, k string, o *bo.Options, clients backends.Backends, - caches map[string]cache.Cache, tracers tracing.Tracers, logger interface{}, + caches map[string]cache.Cache, tracers tracing.Tracers, logger logging.Logger, dryRun bool) error { var client backends.Backend @@ -174,7 +173,7 @@ func registerBackendRoutes(r router.Router, metricsRouter router.Router, } if !dryRun { - tl.Info(logger, "registering route paths", tl.Pairs{"backendName": k, + logger.Info("registering route paths", logging.Pairs{"backendName": k, "backendProvider": o.Provider, "upstreamHost": o.Host}) } @@ -200,8 +199,8 @@ func registerBackendRoutes(r router.Router, metricsRouter router.Router, if h, ok := client.Handlers()["health"]; ok && o.Name != "" && metricsRouter != nil && (o.HealthCheck == nil || o.HealthCheck.Verb != "x") { hp := strings.Replace(conf.Main.HealthHandlerPath+"/"+o.Name, "//", "/", -1) - tl.Debug(logger, "registering health handler path", - tl.Pairs{"path": hp, "backendName": o.Name, + logger.Debug("registering health handler path", + logging.Pairs{"path": hp, "backendName": o.Name, "upstreamPath": o.HealthCheck.Path, "upstreamVerb": o.HealthCheck.Verb}) metricsRouter.RegisterRoute(hp, nil, nil, false, @@ -218,7 +217,7 @@ func registerBackendRoutes(r router.Router, metricsRouter router.Router, func RegisterPathRoutes(r router.Router, handlers map[string]http.Handler, client backends.Backend, o *bo.Options, c cache.Cache, paths map[string]*po.Options, tracers tracing.Tracers, - healthHandlerPath string, logger interface{}) { + healthHandlerPath string, logger logging.Logger) { if o == nil { return @@ -279,8 +278,8 @@ func RegisterPathRoutes(r router.Router, handlers map[string]http.Handler, p.Handler = h plist = append(plist, k) } else { - tl.Info(logger, "invalid handler name for path", - tl.Pairs{"path": p.Path, "handlerName": p.HandlerName}) + logger.Info("invalid handler name for path", + logging.Pairs{"path": p.Path, "handlerName": p.HandlerName}) deletes = append(deletes, p.Path) } } @@ -295,8 +294,8 @@ func RegisterPathRoutes(r router.Router, handlers map[string]http.Handler, pathPrefix := "/" + o.Name handledPath := pathPrefix + p.Path - tl.Debug(logger, "registering backend handler path", - tl.Pairs{"backendName": o.Name, "path": v, "handlerName": p.HandlerName, + logger.Debug("registering backend handler path", + logging.Pairs{"backendName": o.Name, "path": v, "handlerName": p.HandlerName, "backendHost": o.Host, "handledPath": handledPath, "matchType": p.MatchType, "frontendHosts": strings.Join(o.Hosts, ",")}) if p.Handler != nil && len(p.Methods) > 0 { @@ -325,7 +324,7 @@ func RegisterPathRoutes(r router.Router, handlers map[string]http.Handler, // RegisterDefaultBackendRoutes will iterate the Backends and register the default routes func RegisterDefaultBackendRoutes(r router.Router, bknds backends.Backends, - logger interface{}, tracers tracing.Tracers) { + logger logging.Logger, tracers tracing.Tracers) { decorate := func(o *bo.Options, po *po.Options, tr *tracing.Tracer, c cache.Cache, client backends.Backend) http.Handler { @@ -358,14 +357,14 @@ func RegisterDefaultBackendRoutes(r router.Router, bknds backends.Backends, if t, ok := tracers[o.TracingConfigName]; ok { tr = t } - tl.Info(logger, - "registering default backend handler paths", tl.Pairs{"backendName": o.Name}) + logger.Info("registering default backend handler paths", + logging.Pairs{"backendName": o.Name}) for _, p := range o.Paths { if p.Handler != nil && len(p.Methods) > 0 { - tl.Debug(logger, + logger.Debug( "registering default backend handler paths", - tl.Pairs{"backendName": o.Name, "path": p.Path, + logging.Pairs{"backendName": o.Name, "path": p.Path, "handlerName": p.HandlerName, "matchType": p.MatchType}) diff --git a/pkg/testutil/testing.go b/pkg/testutil/testing.go index 0e0ed25d1..2719cabee 100644 --- a/pkg/testutil/testing.go +++ b/pkg/testutil/testing.go @@ -30,7 +30,7 @@ import ( bo "github.com/trickstercache/trickster/v2/pkg/backends/options" cr "github.com/trickstercache/trickster/v2/pkg/cache/registration" "github.com/trickstercache/trickster/v2/pkg/config" - tl "github.com/trickstercache/trickster/v2/pkg/observability/logging" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" "github.com/trickstercache/trickster/v2/pkg/observability/tracing" to "github.com/trickstercache/trickster/v2/pkg/observability/tracing/options" tr "github.com/trickstercache/trickster/v2/pkg/observability/tracing/registration" @@ -117,7 +117,7 @@ func NewTestInstance( return nil, nil, nil, nil, fmt.Errorf("could not load configuration: %s", err.Error()) } - caches := cr.LoadCachesFromConfig(conf, tl.ConsoleLogger("error")) + caches := cr.LoadCachesFromConfig(conf, logging.ConsoleLogger("error")) cache, ok := caches["default"] if !ok { return nil, nil, nil, nil, err @@ -135,7 +135,7 @@ func NewTestInstance( var tracer *tracing.Tracer - logger := tl.ConsoleLogger("error") + logger := logging.ConsoleLogger("error") if o.TracingConfigName != "" { if tc, ok := conf.TracingConfigs[o.TracingConfigName]; ok { tracer, _ = tr.GetTracer(tc, logger, true) @@ -186,7 +186,7 @@ func NewTestTracer() *tracing.Tracer { tc := to.New() tc.Name = "test" tc.Provider = "stdout" - tracer, _ := tr.GetTracer(tc, tl.ConsoleLogger("warn"), true) + tracer, _ := tr.GetTracer(tc, logging.ConsoleLogger("warn"), true) return tracer } diff --git a/pkg/timeseries/timerangequery.go b/pkg/timeseries/timerangequery.go index bbeecb7d9..cf0901ede 100644 --- a/pkg/timeseries/timerangequery.go +++ b/pkg/timeseries/timerangequery.go @@ -55,7 +55,7 @@ type TimeRangeQuery struct { // ValueFieldDefinitions contains the definitions for Value columns in the timeseries, based on the query ValueFieldDefinitions []FieldDefinition `msg:"vfdefs"` // ParsedQuery is a member for the vendor-specific query object - ParsedQuery interface{} `msg:"-"` + ParsedQuery any `msg:"-"` } // Clone returns an exact copy of a TimeRangeQuery diff --git a/pkg/util/middleware/config_context.go b/pkg/util/middleware/config_context.go index 7e477b1c9..e4b45b687 100644 --- a/pkg/util/middleware/config_context.go +++ b/pkg/util/middleware/config_context.go @@ -17,27 +17,22 @@ package middleware import ( - "math/rand" "net/http" - "time" "github.com/trickstercache/trickster/v2/pkg/backends" bo "github.com/trickstercache/trickster/v2/pkg/backends/options" "github.com/trickstercache/trickster/v2/pkg/cache" + "github.com/trickstercache/trickster/v2/pkg/observability/logging" "github.com/trickstercache/trickster/v2/pkg/observability/tracing" "github.com/trickstercache/trickster/v2/pkg/proxy/context" po "github.com/trickstercache/trickster/v2/pkg/proxy/paths/options" "github.com/trickstercache/trickster/v2/pkg/proxy/request" ) -func init() { - rand.Seed(time.Now().UnixNano()) -} - // WithResourcesContext ... func WithResourcesContext(client backends.Backend, o *bo.Options, c cache.Cache, p *po.Options, t *tracing.Tracer, - l interface{}, next http.Handler) http.Handler { + l logging.Logger, next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if o != nil && (o.LatencyMinMS > 0 || o.LatencyMaxMS > 0) { diff --git a/vendor/github.com/go-kit/log/.gitignore b/vendor/github.com/go-kit/log/.gitignore deleted file mode 100644 index 66fd13c90..000000000 --- a/vendor/github.com/go-kit/log/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib - -# Test binary, built with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -# Dependency directories (remove the comment below to include it) -# vendor/ diff --git a/vendor/github.com/go-kit/log/LICENSE b/vendor/github.com/go-kit/log/LICENSE deleted file mode 100644 index bb5bdb9cb..000000000 --- a/vendor/github.com/go-kit/log/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2021 Go kit - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/go-kit/log/README.md b/vendor/github.com/go-kit/log/README.md deleted file mode 100644 index 806779465..000000000 --- a/vendor/github.com/go-kit/log/README.md +++ /dev/null @@ -1,156 +0,0 @@ -# package log - -[![Go Reference](https://pkg.go.dev/badge/github.com/go-kit/log.svg)](https://pkg.go.dev/github.com/go-kit/log) -[![Go Report Card](https://goreportcard.com/badge/go-kit/log)](https://goreportcard.com/report/go-kit/log) -[![GitHub Actions](https://github.com/go-kit/log/actions/workflows/test.yml/badge.svg)](https://github.com/go-kit/log/actions/workflows/test.yml) -[![Coverage Status](https://coveralls.io/repos/github/go-kit/log/badge.svg?branch=main)](https://coveralls.io/github/go-kit/log?branch=main) - -`package log` provides a minimal interface for structured logging in services. -It may be wrapped to encode conventions, enforce type-safety, provide leveled -logging, and so on. It can be used for both typical application log events, -and log-structured data streams. - -## Structured logging - -Structured logging is, basically, conceding to the reality that logs are -_data_, and warrant some level of schematic rigor. Using a stricter, -key/value-oriented message format for our logs, containing contextual and -semantic information, makes it much easier to get insight into the -operational activity of the systems we build. Consequently, `package log` is -of the strong belief that "[the benefits of structured logging outweigh the -minimal effort involved](https://www.thoughtworks.com/radar/techniques/structured-logging)". - -Migrating from unstructured to structured logging is probably a lot easier -than you'd expect. - -```go -// Unstructured -log.Printf("HTTP server listening on %s", addr) - -// Structured -logger.Log("transport", "HTTP", "addr", addr, "msg", "listening") -``` - -## Usage - -### Typical application logging - -```go -w := log.NewSyncWriter(os.Stderr) -logger := log.NewLogfmtLogger(w) -logger.Log("question", "what is the meaning of life?", "answer", 42) - -// Output: -// question="what is the meaning of life?" answer=42 -``` - -### Contextual Loggers - -```go -func main() { - var logger log.Logger - logger = log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr)) - logger = log.With(logger, "instance_id", 123) - - logger.Log("msg", "starting") - NewWorker(log.With(logger, "component", "worker")).Run() - NewSlacker(log.With(logger, "component", "slacker")).Run() -} - -// Output: -// instance_id=123 msg=starting -// instance_id=123 component=worker msg=running -// instance_id=123 component=slacker msg=running -``` - -### Interact with stdlib logger - -Redirect stdlib logger to Go kit logger. - -```go -import ( - "os" - stdlog "log" - kitlog "github.com/go-kit/log" -) - -func main() { - logger := kitlog.NewJSONLogger(kitlog.NewSyncWriter(os.Stdout)) - stdlog.SetOutput(kitlog.NewStdlibAdapter(logger)) - stdlog.Print("I sure like pie") -} - -// Output: -// {"msg":"I sure like pie","ts":"2016/01/01 12:34:56"} -``` - -Or, if, for legacy reasons, you need to pipe all of your logging through the -stdlib log package, you can redirect Go kit logger to the stdlib logger. - -```go -logger := kitlog.NewLogfmtLogger(kitlog.StdlibWriter{}) -logger.Log("legacy", true, "msg", "at least it's something") - -// Output: -// 2016/01/01 12:34:56 legacy=true msg="at least it's something" -``` - -### Timestamps and callers - -```go -var logger log.Logger -logger = log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr)) -logger = log.With(logger, "ts", log.DefaultTimestampUTC, "caller", log.DefaultCaller) - -logger.Log("msg", "hello") - -// Output: -// ts=2016-01-01T12:34:56Z caller=main.go:15 msg=hello -``` - -## Levels - -Log levels are supported via the [level package](https://godoc.org/github.com/go-kit/log/level). - -## Supported output formats - -- [Logfmt](https://brandur.org/logfmt) ([see also](https://blog.codeship.com/logfmt-a-log-format-thats-easy-to-read-and-write)) -- JSON - -## Enhancements - -`package log` is centered on the one-method Logger interface. - -```go -type Logger interface { - Log(keyvals ...interface{}) error -} -``` - -This interface, and its supporting code like is the product of much iteration -and evaluation. For more details on the evolution of the Logger interface, -see [The Hunt for a Logger Interface](http://go-talks.appspot.com/github.com/ChrisHines/talks/structured-logging/structured-logging.slide#1), -a talk by [Chris Hines](https://github.com/ChrisHines). -Also, please see -[#63](https://github.com/go-kit/kit/issues/63), -[#76](https://github.com/go-kit/kit/pull/76), -[#131](https://github.com/go-kit/kit/issues/131), -[#157](https://github.com/go-kit/kit/pull/157), -[#164](https://github.com/go-kit/kit/issues/164), and -[#252](https://github.com/go-kit/kit/pull/252) -to review historical conversations about package log and the Logger interface. - -Value-add packages and suggestions, -like improvements to [the leveled logger](https://godoc.org/github.com/go-kit/log/level), -are of course welcome. Good proposals should - -- Be composable with [contextual loggers](https://godoc.org/github.com/go-kit/log#With), -- Not break the behavior of [log.Caller](https://godoc.org/github.com/go-kit/log#Caller) in any wrapped contextual loggers, and -- Be friendly to packages that accept only an unadorned log.Logger. - -## Benchmarks & comparisons - -There are a few Go logging benchmarks and comparisons that include Go kit's package log. - -- [imkira/go-loggers-bench](https://github.com/imkira/go-loggers-bench) includes kit/log -- [uber-common/zap](https://github.com/uber-common/zap), a zero-alloc logging library, includes a comparison with kit/log diff --git a/vendor/github.com/go-kit/log/doc.go b/vendor/github.com/go-kit/log/doc.go deleted file mode 100644 index f744382fe..000000000 --- a/vendor/github.com/go-kit/log/doc.go +++ /dev/null @@ -1,116 +0,0 @@ -// Package log provides a structured logger. -// -// Structured logging produces logs easily consumed later by humans or -// machines. Humans might be interested in debugging errors, or tracing -// specific requests. Machines might be interested in counting interesting -// events, or aggregating information for off-line processing. In both cases, -// it is important that the log messages are structured and actionable. -// Package log is designed to encourage both of these best practices. -// -// Basic Usage -// -// The fundamental interface is Logger. Loggers create log events from -// key/value data. The Logger interface has a single method, Log, which -// accepts a sequence of alternating key/value pairs, which this package names -// keyvals. -// -// type Logger interface { -// Log(keyvals ...interface{}) error -// } -// -// Here is an example of a function using a Logger to create log events. -// -// func RunTask(task Task, logger log.Logger) string { -// logger.Log("taskID", task.ID, "event", "starting task") -// ... -// logger.Log("taskID", task.ID, "event", "task complete") -// } -// -// The keys in the above example are "taskID" and "event". The values are -// task.ID, "starting task", and "task complete". Every key is followed -// immediately by its value. -// -// Keys are usually plain strings. Values may be any type that has a sensible -// encoding in the chosen log format. With structured logging it is a good -// idea to log simple values without formatting them. This practice allows -// the chosen logger to encode values in the most appropriate way. -// -// Contextual Loggers -// -// A contextual logger stores keyvals that it includes in all log events. -// Building appropriate contextual loggers reduces repetition and aids -// consistency in the resulting log output. With, WithPrefix, and WithSuffix -// add context to a logger. We can use With to improve the RunTask example. -// -// func RunTask(task Task, logger log.Logger) string { -// logger = log.With(logger, "taskID", task.ID) -// logger.Log("event", "starting task") -// ... -// taskHelper(task.Cmd, logger) -// ... -// logger.Log("event", "task complete") -// } -// -// The improved version emits the same log events as the original for the -// first and last calls to Log. Passing the contextual logger to taskHelper -// enables each log event created by taskHelper to include the task.ID even -// though taskHelper does not have access to that value. Using contextual -// loggers this way simplifies producing log output that enables tracing the -// life cycle of individual tasks. (See the Contextual example for the full -// code of the above snippet.) -// -// Dynamic Contextual Values -// -// A Valuer function stored in a contextual logger generates a new value each -// time an event is logged. The Valuer example demonstrates how this feature -// works. -// -// Valuers provide the basis for consistently logging timestamps and source -// code location. The log package defines several valuers for that purpose. -// See Timestamp, DefaultTimestamp, DefaultTimestampUTC, Caller, and -// DefaultCaller. A common logger initialization sequence that ensures all log -// entries contain a timestamp and source location looks like this: -// -// logger := log.NewLogfmtLogger(log.NewSyncWriter(os.Stdout)) -// logger = log.With(logger, "ts", log.DefaultTimestampUTC, "caller", log.DefaultCaller) -// -// Concurrent Safety -// -// Applications with multiple goroutines want each log event written to the -// same logger to remain separate from other log events. Package log provides -// two simple solutions for concurrent safe logging. -// -// NewSyncWriter wraps an io.Writer and serializes each call to its Write -// method. Using a SyncWriter has the benefit that the smallest practical -// portion of the logging logic is performed within a mutex, but it requires -// the formatting Logger to make only one call to Write per log event. -// -// NewSyncLogger wraps any Logger and serializes each call to its Log method. -// Using a SyncLogger has the benefit that it guarantees each log event is -// handled atomically within the wrapped logger, but it typically serializes -// both the formatting and output logic. Use a SyncLogger if the formatting -// logger may perform multiple writes per log event. -// -// Error Handling -// -// This package relies on the practice of wrapping or decorating loggers with -// other loggers to provide composable pieces of functionality. It also means -// that Logger.Log must return an error because some -// implementations—especially those that output log data to an io.Writer—may -// encounter errors that cannot be handled locally. This in turn means that -// Loggers that wrap other loggers should return errors from the wrapped -// logger up the stack. -// -// Fortunately, the decorator pattern also provides a way to avoid the -// necessity to check for errors every time an application calls Logger.Log. -// An application required to panic whenever its Logger encounters -// an error could initialize its logger as follows. -// -// fmtlogger := log.NewLogfmtLogger(log.NewSyncWriter(os.Stdout)) -// logger := log.LoggerFunc(func(keyvals ...interface{}) error { -// if err := fmtlogger.Log(keyvals...); err != nil { -// panic(err) -// } -// return nil -// }) -package log diff --git a/vendor/github.com/go-kit/log/json_logger.go b/vendor/github.com/go-kit/log/json_logger.go deleted file mode 100644 index d0faed4f0..000000000 --- a/vendor/github.com/go-kit/log/json_logger.go +++ /dev/null @@ -1,91 +0,0 @@ -package log - -import ( - "encoding" - "encoding/json" - "fmt" - "io" - "reflect" -) - -type jsonLogger struct { - io.Writer -} - -// NewJSONLogger returns a Logger that encodes keyvals to the Writer as a -// single JSON object. Each log event produces no more than one call to -// w.Write. The passed Writer must be safe for concurrent use by multiple -// goroutines if the returned Logger will be used concurrently. -func NewJSONLogger(w io.Writer) Logger { - return &jsonLogger{w} -} - -func (l *jsonLogger) Log(keyvals ...interface{}) error { - n := (len(keyvals) + 1) / 2 // +1 to handle case when len is odd - m := make(map[string]interface{}, n) - for i := 0; i < len(keyvals); i += 2 { - k := keyvals[i] - var v interface{} = ErrMissingValue - if i+1 < len(keyvals) { - v = keyvals[i+1] - } - merge(m, k, v) - } - enc := json.NewEncoder(l.Writer) - enc.SetEscapeHTML(false) - return enc.Encode(m) -} - -func merge(dst map[string]interface{}, k, v interface{}) { - var key string - switch x := k.(type) { - case string: - key = x - case fmt.Stringer: - key = safeString(x) - default: - key = fmt.Sprint(x) - } - - // We want json.Marshaler and encoding.TextMarshaller to take priority over - // err.Error() and v.String(). But json.Marshall (called later) does that by - // default so we force a no-op if it's one of those 2 case. - switch x := v.(type) { - case json.Marshaler: - case encoding.TextMarshaler: - case error: - v = safeError(x) - case fmt.Stringer: - v = safeString(x) - } - - dst[key] = v -} - -func safeString(str fmt.Stringer) (s string) { - defer func() { - if panicVal := recover(); panicVal != nil { - if v := reflect.ValueOf(str); v.Kind() == reflect.Ptr && v.IsNil() { - s = "NULL" - } else { - s = fmt.Sprintf("PANIC in String method: %v", panicVal) - } - } - }() - s = str.String() - return -} - -func safeError(err error) (s interface{}) { - defer func() { - if panicVal := recover(); panicVal != nil { - if v := reflect.ValueOf(err); v.Kind() == reflect.Ptr && v.IsNil() { - s = nil - } else { - s = fmt.Sprintf("PANIC in Error method: %v", panicVal) - } - } - }() - s = err.Error() - return -} diff --git a/vendor/github.com/go-kit/log/level/doc.go b/vendor/github.com/go-kit/log/level/doc.go deleted file mode 100644 index fd681dcf9..000000000 --- a/vendor/github.com/go-kit/log/level/doc.go +++ /dev/null @@ -1,33 +0,0 @@ -// Package level implements leveled logging on top of Go kit's log package. To -// use the level package, create a logger as per normal in your func main, and -// wrap it with level.NewFilter. -// -// var logger log.Logger -// logger = log.NewLogfmtLogger(os.Stderr) -// logger = level.NewFilter(logger, level.AllowInfo()) // <-- -// logger = log.With(logger, "ts", log.DefaultTimestampUTC) -// -// It's also possible to configure log level from a string. For instance from -// a flag, environment variable or configuration file. -// -// fs := flag.NewFlagSet("myprogram") -// lvl := fs.String("log", "info", "debug, info, warn, error") -// -// var logger log.Logger -// logger = log.NewLogfmtLogger(os.Stderr) -// logger = level.NewFilter(logger, level.Allow(level.ParseDefault(*lvl, level.InfoValue()))) // <-- -// logger = log.With(logger, "ts", log.DefaultTimestampUTC) -// -// Then, at the callsites, use one of the level.Debug, Info, Warn, or Error -// helper methods to emit leveled log events. -// -// logger.Log("foo", "bar") // as normal, no level -// level.Debug(logger).Log("request_id", reqID, "trace_data", trace.Get()) -// if value > 100 { -// level.Error(logger).Log("value", value) -// } -// -// NewFilter allows precise control over what happens when a log event is -// emitted without a level key, or if a squelched level is used. Check the -// Option functions for details. -package level diff --git a/vendor/github.com/go-kit/log/level/level.go b/vendor/github.com/go-kit/log/level/level.go deleted file mode 100644 index c641d9855..000000000 --- a/vendor/github.com/go-kit/log/level/level.go +++ /dev/null @@ -1,256 +0,0 @@ -package level - -import ( - "errors" - "strings" - - "github.com/go-kit/log" -) - -// ErrInvalidLevelString is returned whenever an invalid string is passed to Parse. -var ErrInvalidLevelString = errors.New("invalid level string") - -// Error returns a logger that includes a Key/ErrorValue pair. -func Error(logger log.Logger) log.Logger { - return log.WithPrefix(logger, Key(), ErrorValue()) -} - -// Warn returns a logger that includes a Key/WarnValue pair. -func Warn(logger log.Logger) log.Logger { - return log.WithPrefix(logger, Key(), WarnValue()) -} - -// Info returns a logger that includes a Key/InfoValue pair. -func Info(logger log.Logger) log.Logger { - return log.WithPrefix(logger, Key(), InfoValue()) -} - -// Debug returns a logger that includes a Key/DebugValue pair. -func Debug(logger log.Logger) log.Logger { - return log.WithPrefix(logger, Key(), DebugValue()) -} - -// NewFilter wraps next and implements level filtering. See the commentary on -// the Option functions for a detailed description of how to configure levels. -// If no options are provided, all leveled log events created with Debug, -// Info, Warn or Error helper methods are squelched and non-leveled log -// events are passed to next unmodified. -func NewFilter(next log.Logger, options ...Option) log.Logger { - l := &logger{ - next: next, - } - for _, option := range options { - option(l) - } - return l -} - -type logger struct { - next log.Logger - allowed level - squelchNoLevel bool - errNotAllowed error - errNoLevel error -} - -func (l *logger) Log(keyvals ...interface{}) error { - var hasLevel, levelAllowed bool - for i := 1; i < len(keyvals); i += 2 { - if v, ok := keyvals[i].(*levelValue); ok { - hasLevel = true - levelAllowed = l.allowed&v.level != 0 - break - } - } - if !hasLevel && l.squelchNoLevel { - return l.errNoLevel - } - if hasLevel && !levelAllowed { - return l.errNotAllowed - } - return l.next.Log(keyvals...) -} - -// Option sets a parameter for the leveled logger. -type Option func(*logger) - -// Allow the provided log level to pass. -func Allow(v Value) Option { - switch v { - case debugValue: - return AllowDebug() - case infoValue: - return AllowInfo() - case warnValue: - return AllowWarn() - case errorValue: - return AllowError() - default: - return AllowNone() - } -} - -// AllowAll is an alias for AllowDebug. -func AllowAll() Option { - return AllowDebug() -} - -// AllowDebug allows error, warn, info and debug level log events to pass. -func AllowDebug() Option { - return allowed(levelError | levelWarn | levelInfo | levelDebug) -} - -// AllowInfo allows error, warn and info level log events to pass. -func AllowInfo() Option { - return allowed(levelError | levelWarn | levelInfo) -} - -// AllowWarn allows error and warn level log events to pass. -func AllowWarn() Option { - return allowed(levelError | levelWarn) -} - -// AllowError allows only error level log events to pass. -func AllowError() Option { - return allowed(levelError) -} - -// AllowNone allows no leveled log events to pass. -func AllowNone() Option { - return allowed(0) -} - -func allowed(allowed level) Option { - return func(l *logger) { l.allowed = allowed } -} - -// Parse a string to its corresponding level value. Valid strings are "debug", -// "info", "warn", and "error". Strings are normalized via strings.TrimSpace and -// strings.ToLower. -func Parse(level string) (Value, error) { - switch strings.TrimSpace(strings.ToLower(level)) { - case debugValue.name: - return debugValue, nil - case infoValue.name: - return infoValue, nil - case warnValue.name: - return warnValue, nil - case errorValue.name: - return errorValue, nil - default: - return nil, ErrInvalidLevelString - } -} - -// ParseDefault calls Parse and returns the default Value on error. -func ParseDefault(level string, def Value) Value { - v, err := Parse(level) - if err != nil { - return def - } - return v -} - -// ErrNotAllowed sets the error to return from Log when it squelches a log -// event disallowed by the configured Allow[Level] option. By default, -// ErrNotAllowed is nil; in this case the log event is squelched with no -// error. -func ErrNotAllowed(err error) Option { - return func(l *logger) { l.errNotAllowed = err } -} - -// SquelchNoLevel instructs Log to squelch log events with no level, so that -// they don't proceed through to the wrapped logger. If SquelchNoLevel is set -// to true and a log event is squelched in this way, the error value -// configured with ErrNoLevel is returned to the caller. -func SquelchNoLevel(squelch bool) Option { - return func(l *logger) { l.squelchNoLevel = squelch } -} - -// ErrNoLevel sets the error to return from Log when it squelches a log event -// with no level. By default, ErrNoLevel is nil; in this case the log event is -// squelched with no error. -func ErrNoLevel(err error) Option { - return func(l *logger) { l.errNoLevel = err } -} - -// NewInjector wraps next and returns a logger that adds a Key/level pair to -// the beginning of log events that don't already contain a level. In effect, -// this gives a default level to logs without a level. -func NewInjector(next log.Logger, level Value) log.Logger { - return &injector{ - next: next, - level: level, - } -} - -type injector struct { - next log.Logger - level interface{} -} - -func (l *injector) Log(keyvals ...interface{}) error { - for i := 1; i < len(keyvals); i += 2 { - if _, ok := keyvals[i].(*levelValue); ok { - return l.next.Log(keyvals...) - } - } - kvs := make([]interface{}, len(keyvals)+2) - kvs[0], kvs[1] = key, l.level - copy(kvs[2:], keyvals) - return l.next.Log(kvs...) -} - -// Value is the interface that each of the canonical level values implement. -// It contains unexported methods that prevent types from other packages from -// implementing it and guaranteeing that NewFilter can distinguish the levels -// defined in this package from all other values. -type Value interface { - String() string - levelVal() -} - -// Key returns the unique key added to log events by the loggers in this -// package. -func Key() interface{} { return key } - -// ErrorValue returns the unique value added to log events by Error. -func ErrorValue() Value { return errorValue } - -// WarnValue returns the unique value added to log events by Warn. -func WarnValue() Value { return warnValue } - -// InfoValue returns the unique value added to log events by Info. -func InfoValue() Value { return infoValue } - -// DebugValue returns the unique value added to log events by Debug. -func DebugValue() Value { return debugValue } - -var ( - // key is of type interface{} so that it allocates once during package - // initialization and avoids allocating every time the value is added to a - // []interface{} later. - key interface{} = "level" - - errorValue = &levelValue{level: levelError, name: "error"} - warnValue = &levelValue{level: levelWarn, name: "warn"} - infoValue = &levelValue{level: levelInfo, name: "info"} - debugValue = &levelValue{level: levelDebug, name: "debug"} -) - -type level byte - -const ( - levelDebug level = 1 << iota - levelInfo - levelWarn - levelError -) - -type levelValue struct { - name string - level -} - -func (v *levelValue) String() string { return v.name } -func (v *levelValue) levelVal() {} diff --git a/vendor/github.com/go-kit/log/log.go b/vendor/github.com/go-kit/log/log.go deleted file mode 100644 index 62e11adac..000000000 --- a/vendor/github.com/go-kit/log/log.go +++ /dev/null @@ -1,179 +0,0 @@ -package log - -import "errors" - -// Logger is the fundamental interface for all log operations. Log creates a -// log event from keyvals, a variadic sequence of alternating keys and values. -// Implementations must be safe for concurrent use by multiple goroutines. In -// particular, any implementation of Logger that appends to keyvals or -// modifies or retains any of its elements must make a copy first. -type Logger interface { - Log(keyvals ...interface{}) error -} - -// ErrMissingValue is appended to keyvals slices with odd length to substitute -// the missing value. -var ErrMissingValue = errors.New("(MISSING)") - -// With returns a new contextual logger with keyvals prepended to those passed -// to calls to Log. If logger is also a contextual logger created by With, -// WithPrefix, or WithSuffix, keyvals is appended to the existing context. -// -// The returned Logger replaces all value elements (odd indexes) containing a -// Valuer with their generated value for each call to its Log method. -func With(logger Logger, keyvals ...interface{}) Logger { - if len(keyvals) == 0 { - return logger - } - l := newContext(logger) - kvs := append(l.keyvals, keyvals...) - if len(kvs)%2 != 0 { - kvs = append(kvs, ErrMissingValue) - } - return &context{ - logger: l.logger, - // Limiting the capacity of the stored keyvals ensures that a new - // backing array is created if the slice must grow in Log or With. - // Using the extra capacity without copying risks a data race that - // would violate the Logger interface contract. - keyvals: kvs[:len(kvs):len(kvs)], - hasValuer: l.hasValuer || containsValuer(keyvals), - sKeyvals: l.sKeyvals, - sHasValuer: l.sHasValuer, - } -} - -// WithPrefix returns a new contextual logger with keyvals prepended to those -// passed to calls to Log. If logger is also a contextual logger created by -// With, WithPrefix, or WithSuffix, keyvals is prepended to the existing context. -// -// The returned Logger replaces all value elements (odd indexes) containing a -// Valuer with their generated value for each call to its Log method. -func WithPrefix(logger Logger, keyvals ...interface{}) Logger { - if len(keyvals) == 0 { - return logger - } - l := newContext(logger) - // Limiting the capacity of the stored keyvals ensures that a new - // backing array is created if the slice must grow in Log or With. - // Using the extra capacity without copying risks a data race that - // would violate the Logger interface contract. - n := len(l.keyvals) + len(keyvals) - if len(keyvals)%2 != 0 { - n++ - } - kvs := make([]interface{}, 0, n) - kvs = append(kvs, keyvals...) - if len(kvs)%2 != 0 { - kvs = append(kvs, ErrMissingValue) - } - kvs = append(kvs, l.keyvals...) - return &context{ - logger: l.logger, - keyvals: kvs, - hasValuer: l.hasValuer || containsValuer(keyvals), - sKeyvals: l.sKeyvals, - sHasValuer: l.sHasValuer, - } -} - -// WithSuffix returns a new contextual logger with keyvals appended to those -// passed to calls to Log. If logger is also a contextual logger created by -// With, WithPrefix, or WithSuffix, keyvals is appended to the existing context. -// -// The returned Logger replaces all value elements (odd indexes) containing a -// Valuer with their generated value for each call to its Log method. -func WithSuffix(logger Logger, keyvals ...interface{}) Logger { - if len(keyvals) == 0 { - return logger - } - l := newContext(logger) - // Limiting the capacity of the stored keyvals ensures that a new - // backing array is created if the slice must grow in Log or With. - // Using the extra capacity without copying risks a data race that - // would violate the Logger interface contract. - n := len(l.sKeyvals) + len(keyvals) - if len(keyvals)%2 != 0 { - n++ - } - kvs := make([]interface{}, 0, n) - kvs = append(kvs, keyvals...) - if len(kvs)%2 != 0 { - kvs = append(kvs, ErrMissingValue) - } - kvs = append(l.sKeyvals, kvs...) - return &context{ - logger: l.logger, - keyvals: l.keyvals, - hasValuer: l.hasValuer, - sKeyvals: kvs, - sHasValuer: l.sHasValuer || containsValuer(keyvals), - } -} - -// context is the Logger implementation returned by With, WithPrefix, and -// WithSuffix. It wraps a Logger and holds keyvals that it includes in all -// log events. Its Log method calls bindValues to generate values for each -// Valuer in the context keyvals. -// -// A context must always have the same number of stack frames between calls to -// its Log method and the eventual binding of Valuers to their value. This -// requirement comes from the functional requirement to allow a context to -// resolve application call site information for a Caller stored in the -// context. To do this we must be able to predict the number of logging -// functions on the stack when bindValues is called. -// -// Two implementation details provide the needed stack depth consistency. -// -// 1. newContext avoids introducing an additional layer when asked to -// wrap another context. -// 2. With, WithPrefix, and WithSuffix avoid introducing an additional -// layer by returning a newly constructed context with a merged keyvals -// rather than simply wrapping the existing context. -type context struct { - logger Logger - keyvals []interface{} - sKeyvals []interface{} // suffixes - hasValuer bool - sHasValuer bool -} - -func newContext(logger Logger) *context { - if c, ok := logger.(*context); ok { - return c - } - return &context{logger: logger} -} - -// Log replaces all value elements (odd indexes) containing a Valuer in the -// stored context with their generated value, appends keyvals, and passes the -// result to the wrapped Logger. -func (l *context) Log(keyvals ...interface{}) error { - kvs := append(l.keyvals, keyvals...) - if len(kvs)%2 != 0 { - kvs = append(kvs, ErrMissingValue) - } - if l.hasValuer { - // If no keyvals were appended above then we must copy l.keyvals so - // that future log events will reevaluate the stored Valuers. - if len(keyvals) == 0 { - kvs = append([]interface{}{}, l.keyvals...) - } - bindValues(kvs[:(len(l.keyvals))]) - } - kvs = append(kvs, l.sKeyvals...) - if l.sHasValuer { - bindValues(kvs[len(kvs)-len(l.sKeyvals):]) - } - return l.logger.Log(kvs...) -} - -// LoggerFunc is an adapter to allow use of ordinary functions as Loggers. If -// f is a function with the appropriate signature, LoggerFunc(f) is a Logger -// object that calls f. -type LoggerFunc func(...interface{}) error - -// Log implements Logger by calling f(keyvals...). -func (f LoggerFunc) Log(keyvals ...interface{}) error { - return f(keyvals...) -} diff --git a/vendor/github.com/go-kit/log/logfmt_logger.go b/vendor/github.com/go-kit/log/logfmt_logger.go deleted file mode 100644 index a00305298..000000000 --- a/vendor/github.com/go-kit/log/logfmt_logger.go +++ /dev/null @@ -1,62 +0,0 @@ -package log - -import ( - "bytes" - "io" - "sync" - - "github.com/go-logfmt/logfmt" -) - -type logfmtEncoder struct { - *logfmt.Encoder - buf bytes.Buffer -} - -func (l *logfmtEncoder) Reset() { - l.Encoder.Reset() - l.buf.Reset() -} - -var logfmtEncoderPool = sync.Pool{ - New: func() interface{} { - var enc logfmtEncoder - enc.Encoder = logfmt.NewEncoder(&enc.buf) - return &enc - }, -} - -type logfmtLogger struct { - w io.Writer -} - -// NewLogfmtLogger returns a logger that encodes keyvals to the Writer in -// logfmt format. Each log event produces no more than one call to w.Write. -// The passed Writer must be safe for concurrent use by multiple goroutines if -// the returned Logger will be used concurrently. -func NewLogfmtLogger(w io.Writer) Logger { - return &logfmtLogger{w} -} - -func (l logfmtLogger) Log(keyvals ...interface{}) error { - enc := logfmtEncoderPool.Get().(*logfmtEncoder) - enc.Reset() - defer logfmtEncoderPool.Put(enc) - - if err := enc.EncodeKeyvals(keyvals...); err != nil { - return err - } - - // Add newline to the end of the buffer - if err := enc.EndRecord(); err != nil { - return err - } - - // The Logger interface requires implementations to be safe for concurrent - // use by multiple goroutines. For this implementation that means making - // only one call to l.w.Write() for each call to Log. - if _, err := l.w.Write(enc.buf.Bytes()); err != nil { - return err - } - return nil -} diff --git a/vendor/github.com/go-kit/log/nop_logger.go b/vendor/github.com/go-kit/log/nop_logger.go deleted file mode 100644 index 1047d626c..000000000 --- a/vendor/github.com/go-kit/log/nop_logger.go +++ /dev/null @@ -1,8 +0,0 @@ -package log - -type nopLogger struct{} - -// NewNopLogger returns a logger that doesn't do anything. -func NewNopLogger() Logger { return nopLogger{} } - -func (nopLogger) Log(...interface{}) error { return nil } diff --git a/vendor/github.com/go-kit/log/staticcheck.conf b/vendor/github.com/go-kit/log/staticcheck.conf deleted file mode 100644 index 528438b97..000000000 --- a/vendor/github.com/go-kit/log/staticcheck.conf +++ /dev/null @@ -1 +0,0 @@ -checks = ["all"] diff --git a/vendor/github.com/go-kit/log/stdlib.go b/vendor/github.com/go-kit/log/stdlib.go deleted file mode 100644 index 0338edbe2..000000000 --- a/vendor/github.com/go-kit/log/stdlib.go +++ /dev/null @@ -1,151 +0,0 @@ -package log - -import ( - "bytes" - "io" - "log" - "regexp" - "strings" -) - -// StdlibWriter implements io.Writer by invoking the stdlib log.Print. It's -// designed to be passed to a Go kit logger as the writer, for cases where -// it's necessary to redirect all Go kit log output to the stdlib logger. -// -// If you have any choice in the matter, you shouldn't use this. Prefer to -// redirect the stdlib log to the Go kit logger via NewStdlibAdapter. -type StdlibWriter struct{} - -// Write implements io.Writer. -func (w StdlibWriter) Write(p []byte) (int, error) { - log.Print(strings.TrimSpace(string(p))) - return len(p), nil -} - -// StdlibAdapter wraps a Logger and allows it to be passed to the stdlib -// logger's SetOutput. It will extract date/timestamps, filenames, and -// messages, and place them under relevant keys. -type StdlibAdapter struct { - Logger - timestampKey string - fileKey string - messageKey string - prefix string - joinPrefixToMsg bool -} - -// StdlibAdapterOption sets a parameter for the StdlibAdapter. -type StdlibAdapterOption func(*StdlibAdapter) - -// TimestampKey sets the key for the timestamp field. By default, it's "ts". -func TimestampKey(key string) StdlibAdapterOption { - return func(a *StdlibAdapter) { a.timestampKey = key } -} - -// FileKey sets the key for the file and line field. By default, it's "caller". -func FileKey(key string) StdlibAdapterOption { - return func(a *StdlibAdapter) { a.fileKey = key } -} - -// MessageKey sets the key for the actual log message. By default, it's "msg". -func MessageKey(key string) StdlibAdapterOption { - return func(a *StdlibAdapter) { a.messageKey = key } -} - -// Prefix configures the adapter to parse a prefix from stdlib log events. If -// you provide a non-empty prefix to the stdlib logger, then your should provide -// that same prefix to the adapter via this option. -// -// By default, the prefix isn't included in the msg key. Set joinPrefixToMsg to -// true if you want to include the parsed prefix in the msg. -func Prefix(prefix string, joinPrefixToMsg bool) StdlibAdapterOption { - return func(a *StdlibAdapter) { a.prefix = prefix; a.joinPrefixToMsg = joinPrefixToMsg } -} - -// NewStdlibAdapter returns a new StdlibAdapter wrapper around the passed -// logger. It's designed to be passed to log.SetOutput. -func NewStdlibAdapter(logger Logger, options ...StdlibAdapterOption) io.Writer { - a := StdlibAdapter{ - Logger: logger, - timestampKey: "ts", - fileKey: "caller", - messageKey: "msg", - } - for _, option := range options { - option(&a) - } - return a -} - -func (a StdlibAdapter) Write(p []byte) (int, error) { - p = a.handlePrefix(p) - - result := subexps(p) - keyvals := []interface{}{} - var timestamp string - if date, ok := result["date"]; ok && date != "" { - timestamp = date - } - if time, ok := result["time"]; ok && time != "" { - if timestamp != "" { - timestamp += " " - } - timestamp += time - } - if timestamp != "" { - keyvals = append(keyvals, a.timestampKey, timestamp) - } - if file, ok := result["file"]; ok && file != "" { - keyvals = append(keyvals, a.fileKey, file) - } - if msg, ok := result["msg"]; ok { - msg = a.handleMessagePrefix(msg) - keyvals = append(keyvals, a.messageKey, msg) - } - if err := a.Logger.Log(keyvals...); err != nil { - return 0, err - } - return len(p), nil -} - -func (a StdlibAdapter) handlePrefix(p []byte) []byte { - if a.prefix != "" { - p = bytes.TrimPrefix(p, []byte(a.prefix)) - } - return p -} - -func (a StdlibAdapter) handleMessagePrefix(msg string) string { - if a.prefix == "" { - return msg - } - - msg = strings.TrimPrefix(msg, a.prefix) - if a.joinPrefixToMsg { - msg = a.prefix + msg - } - return msg -} - -const ( - logRegexpDate = `(?P[0-9]{4}/[0-9]{2}/[0-9]{2})?[ ]?` - logRegexpTime = `(?P