From 63fe2a125f2a3237463fa880c31ecd52b009f71c Mon Sep 17 00:00:00 2001 From: Dmitry Monakhov Date: Thu, 5 Dec 2019 10:03:52 +0300 Subject: [PATCH] Add log/fields helpers for keys from specification Opentracing spec specify prefered names for log messages [1] This patch adds declaration for fields which are meaningful for golang - log: add helpers function for spec keys - ext: add LogError() helper for error LogError() helper can not be declarated in log package because it depends opentrace.Span which result in cyclic depencency Footnotes: [1] https://github.com/opentracing/specification/blob/master/semantic_conventions.md#log-fields-table --- ext/field.go | 17 ++++++++++++++++ ext/field_test.go | 50 +++++++++++++++++++++++++++++++++++++++++++++++ log/field.go | 10 ++++++++++ log/field_test.go | 8 ++++++++ 4 files changed, 85 insertions(+) create mode 100644 ext/field.go create mode 100644 ext/field_test.go diff --git a/ext/field.go b/ext/field.go new file mode 100644 index 0000000..8282bd7 --- /dev/null +++ b/ext/field.go @@ -0,0 +1,17 @@ +package ext + +import ( + "github.com/opentracing/opentracing-go" + "github.com/opentracing/opentracing-go/log" +) + +// LogError sets the error=true tag on the Span and logs err as an "error" event. +func LogError(span opentracing.Span, err error, fields ...log.Field) { + Error.Set(span, true) + ef := []log.Field{ + log.Event("error"), + log.Error(err), + } + ef = append(ef, fields...) + span.LogFields(ef...) +} diff --git a/ext/field_test.go b/ext/field_test.go new file mode 100644 index 0000000..8947840 --- /dev/null +++ b/ext/field_test.go @@ -0,0 +1,50 @@ +package ext_test + +import ( + "fmt" + "reflect" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/opentracing/opentracing-go/ext" + "github.com/opentracing/opentracing-go/log" + "github.com/opentracing/opentracing-go/mocktracer" +) + +func TestLogError(t *testing.T) { + tracer := mocktracer.New() + span := tracer.StartSpan("my-trace") + ext.Component.Set(span, "my-awesome-library") + ext.SamplingPriority.Set(span, 1) + err := fmt.Errorf("my error") + ext.LogError(span, err, log.Message("my optional msg text")) + + span.Finish() + + rawSpan := tracer.FinishedSpans()[0] + assert.Equal(t, map[string]interface{}{ + "component": "my-awesome-library", + "error": true, + }, rawSpan.Tags()) + + assert.Equal(t, len(rawSpan.Logs()), 1) + fields := rawSpan.Logs()[0].Fields + assert.Equal(t, []mocktracer.MockKeyValue{ + { + Key: "event", + ValueKind: reflect.String, + ValueString: "error", + }, + { + Key: "error", + ValueKind: reflect.String, + ValueString: err.Error(), + }, + { + Key: "message", + ValueKind: reflect.String, + ValueString: "my optional msg text", + }, + }, fields) +} diff --git a/log/field.go b/log/field.go index 22c835f..5e92cc8 100644 --- a/log/field.go +++ b/log/field.go @@ -143,6 +143,16 @@ func Object(key string, obj interface{}) Field { } } +// Event creates a string-valued Field for span logs with key="event" and value=val. +func Event(val string) Field { + return String("event", val) +} + +// Message creates a string-valued Field for span logs with key="message" and value=val. +func Message(val string) Field { + return String("message", val) +} + // LazyLogger allows for user-defined, late-bound logging of arbitrary data type LazyLogger func(fv Encoder) diff --git a/log/field_test.go b/log/field_test.go index 73ab172..7fddf68 100644 --- a/log/field_test.go +++ b/log/field_test.go @@ -34,6 +34,14 @@ func TestFieldString(t *testing.T) { field: Noop(), expected: ":", }, + { + field: Event("test"), + expected: "event:test", + }, + { + field: Message("test2"), + expected: "message:test2", + }, } for i, tc := range testCases { if str := tc.field.String(); str != tc.expected {