From 5f26364f4f18d893cf5960fd4511f80ffe5410c5 Mon Sep 17 00:00:00 2001 From: DarcyRaynerDD Date: Wed, 1 Apr 2020 13:32:43 -0400 Subject: [PATCH 1/2] Always send enhanced metrics through logs --- ddlambda.go | 2 +- internal/logger/log.go | 16 +++++- internal/metrics/listener.go | 8 +-- internal/metrics/listener_test.go | 86 ++++++++++++++++++++++--------- 4 files changed, 83 insertions(+), 29 deletions(-) diff --git a/ddlambda.go b/ddlambda.go index 2c22349f..12b52c10 100644 --- a/ddlambda.go +++ b/ddlambda.go @@ -129,7 +129,7 @@ func MetricWithTimestamp(metric string, value float64, timestamp time.Time, tags logger.Error(fmt.Errorf("couldn't get metrics listener from current context")) return } - listener.AddDistributionMetric(metric, value, timestamp, tags...) + listener.AddDistributionMetric(metric, value, timestamp, false, tags...) } // InvokeDryRun is a utility to easily run your lambda for testing diff --git a/internal/logger/log.go b/internal/logger/log.go index 1af13248..d3a1de75 100644 --- a/internal/logger/log.go +++ b/internal/logger/log.go @@ -3,7 +3,9 @@ package logger import ( "encoding/json" "fmt" + "io" "log" + "os" ) // LogLevel represents the level of logging that should be performed @@ -17,7 +19,8 @@ const ( ) var ( - logLevel = LevelError + logLevel = LevelError + output io.Writer = os.Stdout ) // SetLogLevel set the level of logging for the ddlambda @@ -25,6 +28,12 @@ func SetLogLevel(ll LogLevel) { logLevel = ll } +// +func SetOutput(w io.Writer) { + log.SetOutput(w) + output = w +} + // Error logs a structured error message to stdout func Error(err error) { @@ -60,3 +69,8 @@ func Debug(message string) { log.Println(string(result)) } + +// Raw prints a raw message to the logs. +func Raw(message string) { + fmt.Fprintln(output, message) +} diff --git a/internal/metrics/listener.go b/internal/metrics/listener.go index 5b000df2..7293bd3c 100644 --- a/internal/metrics/listener.go +++ b/internal/metrics/listener.go @@ -99,12 +99,12 @@ func (l *Listener) HandlerFinished(ctx context.Context) { } // AddDistributionMetric sends a distribution metric -func (l *Listener) AddDistributionMetric(metric string, value float64, timestamp time.Time, tags ...string) { +func (l *Listener) AddDistributionMetric(metric string, value float64, timestamp time.Time, forceLogForwarder bool, tags ...string) { // We add our own runtime tag to the metric for version tracking tags = append(tags, getRuntimeTag()) - if l.config.ShouldUseLogForwarder { + if l.config.ShouldUseLogForwarder || forceLogForwarder { logger.Debug("sending metric via log forwarder") unixTime := timestamp.Unix() lm := logMetric{ @@ -119,7 +119,7 @@ func (l *Listener) AddDistributionMetric(metric string, value float64, timestamp return } payload := string(result) - println(payload) + logger.Raw(payload) return } m := Distribution{ @@ -140,7 +140,7 @@ func getRuntimeTag() string { func (l *Listener) submitEnhancedMetrics(metricName string, ctx context.Context) { if l.config.EnhancedMetrics { tags := getEnhancedMetricsTags(ctx) - l.AddDistributionMetric(fmt.Sprintf("aws.lambda.enhanced.%s", metricName), 1, time.Now(), tags...) + l.AddDistributionMetric(fmt.Sprintf("aws.lambda.enhanced.%s", metricName), 1, time.Now(), true, tags...) } } diff --git a/internal/metrics/listener_test.go b/internal/metrics/listener_test.go index 33067591..26e95956 100644 --- a/internal/metrics/listener_test.go +++ b/internal/metrics/listener_test.go @@ -9,17 +9,30 @@ package metrics import ( + "bytes" "context" "encoding/json" - "github.com/aws/aws-lambda-go/lambdacontext" "net/http" "net/http/httptest" + "os" + "strings" "testing" "time" + "github.com/DataDog/datadog-lambda-go/internal/logger" + "github.com/aws/aws-lambda-go/lambdacontext" + "github.com/stretchr/testify/assert" ) +func captureOutput(f func()) string { + var buf bytes.Buffer + logger.SetOutput(&buf) + f() + logger.SetOutput(os.Stderr) + return buf.String() +} + func TestHandlerAddsItselfToContext(t *testing.T) { listener := MakeListener(Config{}) ctx := listener.HandlerStarted(context.Background(), json.RawMessage{}) @@ -47,7 +60,7 @@ func TestAddDistributionMetricWithAPI(t *testing.T) { listener := MakeListener(Config{APIKey: "12345", Site: server.URL}) ctx := listener.HandlerStarted(context.Background(), json.RawMessage{}) - listener.AddDistributionMetric("the-metric", 2, time.Now(), "tag:a", "tag:b") + listener.AddDistributionMetric("the-metric", 2, time.Now(), false, "tag:a", "tag:b") listener.HandlerFinished(ctx) assert.True(t, called) } @@ -62,7 +75,21 @@ func TestAddDistributionMetricWithLogForwarder(t *testing.T) { listener := MakeListener(Config{APIKey: "12345", Site: server.URL, ShouldUseLogForwarder: true}) ctx := listener.HandlerStarted(context.Background(), json.RawMessage{}) - listener.AddDistributionMetric("the-metric", 2, time.Now(), "tag:a", "tag:b") + listener.AddDistributionMetric("the-metric", 2, time.Now(), false, "tag:a", "tag:b") + listener.HandlerFinished(ctx) + assert.False(t, called) +} +func TestAddDistributionMetricWithForceLogForwarder(t *testing.T) { + called := false + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + called = true + w.WriteHeader(http.StatusCreated) + })) + defer server.Close() + + listener := MakeListener(Config{APIKey: "12345", Site: server.URL, ShouldUseLogForwarder: false}) + ctx := listener.HandlerStarted(context.Background(), json.RawMessage{}) + listener.AddDistributionMetric("the-metric", 2, time.Now(), true, "tag:a", "tag:b") listener.HandlerFinished(ctx) assert.False(t, called) } @@ -96,17 +123,21 @@ func TestSubmitEnhancedMetrics(t *testing.T) { defer server.Close() ml := MakeListener( Config{ - APIKey: "abc-123", - Site: server.URL, - EnhancedMetrics: true, + APIKey: "abc-123", + Site: server.URL, + EnhancedMetrics: true, }, ) ctx := context.WithValue(context.Background(), "cold_start", false) - ctx = ml.HandlerStarted(ctx, json.RawMessage{}) - ml.HandlerFinished(ctx) + output := captureOutput(func() { + ctx = ml.HandlerStarted(ctx, json.RawMessage{}) + ml.HandlerFinished(ctx) + }) - assert.True(t, called) + assert.False(t, called) + expected := "{\"m\":\"aws.lambda.enhanced.invocations\",\"v\":1," + assert.True(t, strings.Contains(output, expected)) } func TestDoNotSubmitEnhancedMetrics(t *testing.T) { @@ -119,17 +150,21 @@ func TestDoNotSubmitEnhancedMetrics(t *testing.T) { ml := MakeListener( Config{ - APIKey: "abc-123", - Site: server.URL, - EnhancedMetrics: false, + APIKey: "abc-123", + Site: server.URL, + EnhancedMetrics: false, }, ) ctx := context.WithValue(context.Background(), "cold_start", true) - ctx = ml.HandlerStarted(ctx, json.RawMessage{}) - ml.HandlerFinished(ctx) + output := captureOutput(func() { + ctx = ml.HandlerStarted(ctx, json.RawMessage{}) + ml.HandlerFinished(ctx) + }) assert.False(t, called) + expected := "{\"m\":\"aws.lambda.enhanced.invocations\",\"v\":1," + assert.False(t, strings.Contains(output, expected)) } func TestSubmitEnhancedMetricsOnlyErrors(t *testing.T) { @@ -142,17 +177,22 @@ func TestSubmitEnhancedMetricsOnlyErrors(t *testing.T) { ml := MakeListener( Config{ - APIKey: "abc-123", - Site: server.URL, - EnhancedMetrics: false, + APIKey: "abc-123", + Site: server.URL, + EnhancedMetrics: false, }, ) + ctx := context.WithValue(context.Background(), "cold_start", true) - ctx = ml.HandlerStarted(ctx, json.RawMessage{}) - ml.config.EnhancedMetrics = true - ctx = context.WithValue(ctx, "error", true) - ml.HandlerFinished(ctx) + output := captureOutput(func() { + ctx = ml.HandlerStarted(ctx, json.RawMessage{}) + ml.config.EnhancedMetrics = true + ctx = context.WithValue(ctx, "error", true) + ml.HandlerFinished(ctx) + }) - assert.True(t, called) -} \ No newline at end of file + assert.False(t, called) + expected := "{\"m\":\"aws.lambda.enhanced.errors\",\"v\":1," + assert.True(t, strings.Contains(output, expected)) +} From f35fc46562b9ca10e799f5915cb0263bb89428bd Mon Sep 17 00:00:00 2001 From: DarcyRaynerDD Date: Wed, 1 Apr 2020 13:55:55 -0400 Subject: [PATCH 2/2] Fix go comment --- internal/logger/log.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/logger/log.go b/internal/logger/log.go index d3a1de75..44b8c7eb 100644 --- a/internal/logger/log.go +++ b/internal/logger/log.go @@ -28,7 +28,7 @@ func SetLogLevel(ll LogLevel) { logLevel = ll } -// +// SetOutput changes the writer for the logger func SetOutput(w io.Writer) { log.SetOutput(w) output = w