Skip to content

Commit

Permalink
Merge pull request #30 from DataDog/darcy.rayner/enhanced-metrics-by-…
Browse files Browse the repository at this point in the history
…default

Always send enhanced metrics through logs
  • Loading branch information
DarcyRaynerDD authored Apr 6, 2020
2 parents 989983d + f35fc46 commit d1b66f5
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 29 deletions.
2 changes: 1 addition & 1 deletion ddlambda.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
16 changes: 15 additions & 1 deletion internal/logger/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ package logger
import (
"encoding/json"
"fmt"
"io"
"log"
"os"
)

// LogLevel represents the level of logging that should be performed
Expand All @@ -17,14 +19,21 @@ const (
)

var (
logLevel = LevelError
logLevel = LevelError
output io.Writer = os.Stdout
)

// SetLogLevel set the level of logging for the ddlambda
func SetLogLevel(ll LogLevel) {
logLevel = ll
}

// SetOutput changes the writer for the logger
func SetOutput(w io.Writer) {
log.SetOutput(w)
output = w
}

// Error logs a structured error message to stdout
func Error(err error) {

Expand Down Expand Up @@ -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)
}
8 changes: 4 additions & 4 deletions internal/metrics/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand All @@ -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{
Expand All @@ -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...)
}
}

Expand Down
86 changes: 63 additions & 23 deletions internal/metrics/listener_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{})
Expand Down Expand Up @@ -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)
}
Expand All @@ -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)
}
Expand Down Expand Up @@ -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) {
Expand All @@ -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) {
Expand All @@ -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)
}
assert.False(t, called)
expected := "{\"m\":\"aws.lambda.enhanced.errors\",\"v\":1,"
assert.True(t, strings.Contains(output, expected))
}

0 comments on commit d1b66f5

Please sign in to comment.