Skip to content

Commit

Permalink
Allow user to not use default dimensions
Browse files Browse the repository at this point in the history
  • Loading branch information
prozz committed Sep 9, 2021
1 parent e4d4fd5 commit 8a30251
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 36 deletions.
79 changes: 45 additions & 34 deletions emf/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ import (

// Logger for metrics with default Context.
type Logger struct {
out io.Writer
timestamp int64
defaultContext Context
contexts []*Context
values map[string]interface{}
out io.Writer
timestamp int64
defaultContext Context
contexts []*Context
values map[string]interface{}
withoutDimensions bool
}

// Context gives ability to add another MetricDirective section for Logger.
Expand All @@ -41,21 +42,40 @@ func WithTimestamp(t time.Time) LoggerOption {
}
}

// WithoutDimensions ignores default AWS Lambda related properties and dimensions.
func WithoutDimensions() LoggerOption {
return func(l *Logger) {
l.withoutDimensions = true
}
}

// New creates logger with reasonable defaults for Lambda functions:
// - Prints to os.Stdout.
// - Context based on Lambda environment variables.
// - Timestamp set to the time when New was called.
// Specify LoggerOptions to customize the logger.
func New(opts ...LoggerOption) *Logger {
l := Logger{
out: os.Stdout,
timestamp: time.Now().UnixNano() / int64(time.Millisecond),
}

// apply any options
for _, opt := range opts {
opt(&l)
}

values := make(map[string]interface{})

// set default properties for lambda function
fnName := os.Getenv("AWS_LAMBDA_FUNCTION_NAME")
if fnName != "" {
values["executionEnvironment"] = os.Getenv("AWS_EXECUTION_ENV")
values["memorySize"] = os.Getenv("AWS_LAMBDA_FUNCTION_MEMORY_SIZE")
values["functionVersion"] = os.Getenv("AWS_LAMBDA_FUNCTION_VERSION")
values["logStreamId"] = os.Getenv("AWS_LAMBDA_LOG_STREAM_NAME")
if !l.withoutDimensions {
// set default properties for lambda function
fnName := os.Getenv("AWS_LAMBDA_FUNCTION_NAME")
if fnName != "" {
values["executionEnvironment"] = os.Getenv("AWS_EXECUTION_ENV")
values["memorySize"] = os.Getenv("AWS_LAMBDA_FUNCTION_MEMORY_SIZE")
values["functionVersion"] = os.Getenv("AWS_LAMBDA_FUNCTION_VERSION")
values["logStreamId"] = os.Getenv("AWS_LAMBDA_LOG_STREAM_NAME")
}
}

// only collect traces which have been sampled
Expand All @@ -64,20 +84,10 @@ func New(opts ...LoggerOption) *Logger {
values["traceId"] = amznTraceID
}

// create a default logger
l := &Logger{
out: os.Stdout,
defaultContext: newContext(values),
values: values,
timestamp: time.Now().UnixNano() / int64(time.Millisecond),
}
l.values = values
l.defaultContext = newContext(values, l.withoutDimensions)

// apply any options
for _, opt := range opts {
opt(l)
}

return l
return &l
}

// Dimension helps builds DimensionSet.
Expand Down Expand Up @@ -201,7 +211,7 @@ func (l *Logger) Log() {

// NewContext creates new context for given logger.
func (l *Logger) NewContext() *Context {
c := newContext(l.values)
c := newContext(l.values, l.withoutDimensions)
l.contexts = append(l.contexts, &c)
return &c
}
Expand Down Expand Up @@ -250,15 +260,16 @@ func (c *Context) MetricFloatAs(name string, value float64, unit MetricUnit) *Co
return c.put(name, value, unit)
}

func newContext(values map[string]interface{}) Context {
func newContext(values map[string]interface{}, withoutDimensions bool) Context {
var defaultDimensions []DimensionSet

// set default dimensions for lambda function
fnName := os.Getenv("AWS_LAMBDA_FUNCTION_NAME")
if fnName != "" {
defaultDimensions = []DimensionSet{{"ServiceName", "ServiceType"}}
values["ServiceType"] = "AWS::Lambda::Function"
values["ServiceName"] = fnName
if !withoutDimensions {
// set default dimensions for lambda function
fnName := os.Getenv("AWS_LAMBDA_FUNCTION_NAME")
if fnName != "" {
defaultDimensions = []DimensionSet{{"ServiceName", "ServiceType"}}
values["ServiceType"] = "AWS::Lambda::Function"
values["ServiceName"] = fnName
}
}

return Context{
Expand Down
11 changes: 11 additions & 0 deletions emf/logger_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,17 @@ func TestNew(t *testing.T) {
timestamp: time.Now().Add(time.Hour).UnixNano() / int64(time.Millisecond),
},
},
{
name: "without dimensions",
opts: []LoggerOption{
WithoutDimensions(),
},
expected: &Logger{
out: os.Stdout,
timestamp: time.Now().UnixNano() / int64(time.Millisecond),
withoutDimensions: false,
},
},
}

for _, tc := range tcs {
Expand Down
28 changes: 26 additions & 2 deletions emf/logger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ import (
func TestEmf(t *testing.T) {
tcs := []struct {
name string
new func(*bytes.Buffer) *emf.Logger
env map[string]string
given func(logger *emf.Logger)
given func(*emf.Logger)
expected string
}{
{
Expand Down Expand Up @@ -171,6 +172,23 @@ func TestEmf(t *testing.T) {
},
expected: "testdata/16.json",
},
{
name: "default properties and dimensions for lambda are ignored",
new: func(buf *bytes.Buffer) *emf.Logger {
return emf.New(emf.WithoutDimensions(), emf.WithWriter(buf))
},
env: map[string]string{
"AWS_LAMBDA_FUNCTION_NAME": "some-func-name",
"AWS_EXECUTION_ENV": "golang",
"AWS_LAMBDA_FUNCTION_MEMORY_SIZE": "128",
"AWS_LAMBDA_FUNCTION_VERSION": "1",
"AWS_LAMBDA_LOG_STREAM_NAME": "log/stream",
},
given: func(logger *emf.Logger) {
logger.Metric("foo", 33)
},
expected: "testdata/17.json",
},
}

for _, tc := range tcs {
Expand All @@ -181,10 +199,16 @@ func TestEmf(t *testing.T) {
}

var buf bytes.Buffer
logger := emf.New(emf.WithWriter(&buf))
var logger *emf.Logger
if tc.new != nil {
logger = tc.new(&buf)
} else {
logger = emf.New(emf.WithWriter(&buf))
}
tc.given(logger)
logger.Log()

println(buf.String())
f, err := ioutil.ReadFile(tc.expected)
if err != nil {
t.Fatal("unable to read file with expected json")
Expand Down
18 changes: 18 additions & 0 deletions emf/testdata/17.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"_aws": {
"Timestamp": "<<PRESENCE>>",
"CloudWatchMetrics": [
{
"Metrics": [
{
"Name": "foo",
"Unit": "None"
}
],
"Namespace": "aws-embedded-metrics",
"Dimensions": null
}
]
},
"foo": 33
}

0 comments on commit 8a30251

Please sign in to comment.