diff --git a/pkg/networkservice/core/trace/client.go b/pkg/networkservice/core/trace/client.go index b4d3fe856..14aed7674 100644 --- a/pkg/networkservice/core/trace/client.go +++ b/pkg/networkservice/core/trace/client.go @@ -1,6 +1,6 @@ -// Copyright (c) 2020 Cisco Systems, Inc. +// Copyright (c) 2020-2023 Cisco Systems, Inc. // -// Copyright (c) 2021 Doc.ai and/or its affiliates. +// Copyright (c) 2021-2023 Doc.ai and/or its affiliates. // // SPDX-License-Identifier: Apache-2.0 // @@ -46,8 +46,8 @@ func NewNetworkServiceClient(traced networkservice.NetworkServiceClient) network func (t *beginTraceClient) Request(ctx context.Context, request *networkservice.NetworkServiceRequest, opts ...grpc.CallOption) (*networkservice.Connection, error) { // Create a new logger - operation := typeutils.GetFuncName(t.traced, "Request") - ctx, finish := withLog(ctx, operation, request.GetConnection().GetId()) + operation := typeutils.GetFuncName(t.traced, methodNameRequest) + ctx, finish := withLog(ctx, operation, methodNameRequest, request.GetConnection().GetId()) defer finish() logRequest(ctx, request, "request") @@ -62,8 +62,8 @@ func (t *beginTraceClient) Request(ctx context.Context, request *networkservice. func (t *beginTraceClient) Close(ctx context.Context, conn *networkservice.Connection, opts ...grpc.CallOption) (*empty.Empty, error) { // Create a new logger - operation := typeutils.GetFuncName(t.traced, "Close") - ctx, finish := withLog(ctx, operation, conn.GetId()) + operation := typeutils.GetFuncName(t.traced, methodNameClose) + ctx, finish := withLog(ctx, operation, methodNameClose, conn.GetId()) defer finish() logRequest(ctx, conn, "close") diff --git a/pkg/networkservice/core/trace/common.go b/pkg/networkservice/core/trace/common.go index 836e99973..df4debfd2 100644 --- a/pkg/networkservice/core/trace/common.go +++ b/pkg/networkservice/core/trace/common.go @@ -1,6 +1,6 @@ -// Copyright (c) 2020 Cisco Systems, Inc. +// Copyright (c) 2020-2023 Cisco Systems, Inc. // -// Copyright (c) 2021 Doc.ai and/or its affiliates. +// Copyright (c) 2021-2023 Doc.ai and/or its affiliates. // // SPDX-License-Identifier: Apache-2.0 // @@ -33,6 +33,11 @@ import ( "github.com/networkservicemesh/sdk/pkg/tools/log" ) +const ( + methodNameRequest = "Request" + methodNameClose = "Close" +) + func logRequest(ctx context.Context, request proto.Message, prefixes ...string) { msg := strings.Join(prefixes, "-") diffMsg := strings.Join(append(prefixes, "diff"), "-") diff --git a/pkg/networkservice/core/trace/context.go b/pkg/networkservice/core/trace/context.go index 1786ccc3e..307f55026 100644 --- a/pkg/networkservice/core/trace/context.go +++ b/pkg/networkservice/core/trace/context.go @@ -1,6 +1,6 @@ -// Copyright (c) 2020-2022 Cisco Systems, Inc. +// Copyright (c) 2020-2023 Cisco Systems, Inc. // -// Copyright (c) 2021-2022 Doc.ai and/or its affiliates. +// Copyright (c) 2021-2023 Doc.ai and/or its affiliates. // // SPDX-License-Identifier: Apache-2.0 // @@ -46,7 +46,7 @@ type traceInfo struct { } // withLog - provides corresponding logger in context -func withLog(parent context.Context, operation, connectionID string) (c context.Context, f func()) { +func withLog(parent context.Context, operation, methodName, connectionID string) (c context.Context, f func()) { if parent == nil { panic("cannot create context from nil parent") } @@ -56,8 +56,10 @@ func withLog(parent context.Context, operation, connectionID string) (c context. if grpcTraceState := grpcutils.TraceFromContext(parent); (grpcTraceState == grpcutils.TraceOn) || (grpcTraceState == grpcutils.TraceUndefined && log.IsTracingEnabled()) { - ctx, sLogger, span, sFinish := spanlogger.FromContext(parent, operation, map[string]interface{}{"type": loggedType, "id": connectionID}) - ctx, lLogger, lFinish := logruslogger.FromSpan(ctx, span, operation, map[string]interface{}{"type": loggedType, "id": connectionID}) + fields := []*log.Field{log.NewField("id", connectionID), log.NewField("type", loggedType)} + + ctx, sLogger, span, sFinish := spanlogger.FromContext(parent, operation, methodName, fields) + ctx, lLogger, lFinish := logruslogger.FromSpan(ctx, span, operation, fields) return withTrace(log.WithLog(ctx, sLogger, lLogger)), func() { sFinish() lFinish() diff --git a/pkg/networkservice/core/trace/server.go b/pkg/networkservice/core/trace/server.go index c3d9b00cf..218f5be4d 100644 --- a/pkg/networkservice/core/trace/server.go +++ b/pkg/networkservice/core/trace/server.go @@ -1,6 +1,6 @@ -// Copyright (c) 2020 Cisco Systems, Inc. +// Copyright (c) 2020-2023 Cisco Systems, Inc. // -// Copyright (c) 2021 Doc.ai and/or its affiliates. +// Copyright (c) 2021-2023 Doc.ai and/or its affiliates. // // SPDX-License-Identifier: Apache-2.0 // @@ -45,8 +45,8 @@ func NewNetworkServiceServer(traced networkservice.NetworkServiceServer) network func (t *beginTraceServer) Request(ctx context.Context, request *networkservice.NetworkServiceRequest) (*networkservice.Connection, error) { // Create a new logger - operation := typeutils.GetFuncName(t.traced, "Request") - ctx, finish := withLog(ctx, operation, request.GetConnection().GetId()) + operation := typeutils.GetFuncName(t.traced, methodNameRequest) + ctx, finish := withLog(ctx, operation, methodNameRequest, request.GetConnection().GetId()) defer finish() logRequest(ctx, request, "request") @@ -61,8 +61,8 @@ func (t *beginTraceServer) Request(ctx context.Context, request *networkservice. func (t *beginTraceServer) Close(ctx context.Context, conn *networkservice.Connection) (*empty.Empty, error) { // Create a new logger - operation := typeutils.GetFuncName(t.traced, "Close") - ctx, finish := withLog(ctx, operation, conn.GetId()) + operation := typeutils.GetFuncName(t.traced, methodNameClose) + ctx, finish := withLog(ctx, operation, methodNameClose, conn.GetId()) defer finish() logRequest(ctx, conn, "close") diff --git a/pkg/registry/core/trace/common.go b/pkg/registry/core/trace/common.go index e2851d615..6af03d9f9 100644 --- a/pkg/registry/core/trace/common.go +++ b/pkg/registry/core/trace/common.go @@ -1,5 +1,7 @@ // Copyright (c) 2021 Doc.ai and/or its affiliates. // +// Copyright (c) 2023 Cisco and/or its affiliates. +// // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -26,6 +28,14 @@ import ( "github.com/networkservicemesh/sdk/pkg/tools/log" ) +const ( + methodNameRegister = "Register" + methodNameUnregister = "Unregister" + methodNameFind = "Find" + methodNameSend = "Send" + methodNameRecv = "Recv" +) + type stackTracer interface { StackTrace() errors.StackTrace } diff --git a/pkg/registry/core/trace/context.go b/pkg/registry/core/trace/context.go index c24c63071..ac09d9a21 100644 --- a/pkg/registry/core/trace/context.go +++ b/pkg/registry/core/trace/context.go @@ -1,6 +1,6 @@ -// Copyright (c) 2020-2022 Cisco Systems, Inc. +// Copyright (c) 2020-2023 Cisco Systems, Inc. // -// Copyright (c) 2021-2022 Doc.ai and/or its affiliates. +// Copyright (c) 2021-2023 Doc.ai and/or its affiliates. // // SPDX-License-Identifier: Apache-2.0 // @@ -32,7 +32,7 @@ const ( ) // withLog - provides corresponding logger in context -func withLog(parent context.Context, operation string) (c context.Context, f func()) { +func withLog(parent context.Context, operation, methodName string) (c context.Context, f func()) { if parent == nil { panic("cannot create context from nil parent") } @@ -42,8 +42,10 @@ func withLog(parent context.Context, operation string) (c context.Context, f fun if grpcTraceState := grpcutils.TraceFromContext(parent); (grpcTraceState == grpcutils.TraceOn) || (grpcTraceState == grpcutils.TraceUndefined && log.IsTracingEnabled()) { - ctx, sLogger, span, sFinish := spanlogger.FromContext(parent, operation, map[string]interface{}{"type": loggedType}) - ctx, lLogger, lFinish := logruslogger.FromSpan(ctx, span, operation, map[string]interface{}{"type": loggedType}) + fields := []*log.Field{log.NewField("type", loggedType)} + + ctx, sLogger, span, sFinish := spanlogger.FromContext(parent, operation, methodName, fields) + ctx, lLogger, lFinish := logruslogger.FromSpan(ctx, span, operation, fields) return log.WithLog(ctx, sLogger, lLogger), func() { sFinish() lFinish() diff --git a/pkg/registry/core/trace/ns_registry.go b/pkg/registry/core/trace/ns_registry.go index 4f4a947aa..fea56d645 100644 --- a/pkg/registry/core/trace/ns_registry.go +++ b/pkg/registry/core/trace/ns_registry.go @@ -44,8 +44,8 @@ type traceNetworkServiceRegistryFindClient struct { } func (t *traceNetworkServiceRegistryFindClient) Recv() (*registry.NetworkServiceResponse, error) { - operation := typeutils.GetFuncName(t.NetworkServiceRegistry_FindClient, "Recv") - ctx, finish := withLog(t.Context(), operation) + operation := typeutils.GetFuncName(t.NetworkServiceRegistry_FindClient, methodNameRecv) + ctx, finish := withLog(t.Context(), operation, methodNameRecv) defer finish() s := streamcontext.NetworkServiceRegistryFindClient(ctx, t.NetworkServiceRegistry_FindClient) @@ -65,8 +65,8 @@ func (t *traceNetworkServiceRegistryFindClient) Recv() (*registry.NetworkService } func (t *traceNetworkServiceRegistryClient) Register(ctx context.Context, in *registry.NetworkService, opts ...grpc.CallOption) (*registry.NetworkService, error) { - operation := typeutils.GetFuncName(t.traced, "Register") - ctx, finish := withLog(ctx, operation) + operation := typeutils.GetFuncName(t.traced, methodNameRegister) + ctx, finish := withLog(ctx, operation, methodNameRegister) defer finish() logObjectTrace(ctx, "register", in) @@ -79,8 +79,8 @@ func (t *traceNetworkServiceRegistryClient) Register(ctx context.Context, in *re return rv, nil } func (t *traceNetworkServiceRegistryClient) Find(ctx context.Context, in *registry.NetworkServiceQuery, opts ...grpc.CallOption) (registry.NetworkServiceRegistry_FindClient, error) { - operation := typeutils.GetFuncName(t.traced, "Find") - ctx, finish := withLog(ctx, operation) + operation := typeutils.GetFuncName(t.traced, methodNameFind) + ctx, finish := withLog(ctx, operation, methodNameFind) defer finish() logObjectTrace(ctx, "find", in) @@ -96,8 +96,8 @@ func (t *traceNetworkServiceRegistryClient) Find(ctx context.Context, in *regist } func (t *traceNetworkServiceRegistryClient) Unregister(ctx context.Context, in *registry.NetworkService, opts ...grpc.CallOption) (*empty.Empty, error) { - operation := typeutils.GetFuncName(t.traced, "Unregister") - ctx, finish := withLog(ctx, operation) + operation := typeutils.GetFuncName(t.traced, methodNameUnregister) + ctx, finish := withLog(ctx, operation, methodNameUnregister) defer finish() logObjectTrace(ctx, "unregister", in) @@ -121,8 +121,8 @@ type traceNetworkServiceRegistryServer struct { } func (t *traceNetworkServiceRegistryServer) Register(ctx context.Context, in *registry.NetworkService) (*registry.NetworkService, error) { - operation := typeutils.GetFuncName(t.traced, "Register") - ctx, finish := withLog(ctx, operation) + operation := typeutils.GetFuncName(t.traced, methodNameRegister) + ctx, finish := withLog(ctx, operation, methodNameRegister) defer finish() logObjectTrace(ctx, "register", in) @@ -136,8 +136,8 @@ func (t *traceNetworkServiceRegistryServer) Register(ctx context.Context, in *re } func (t *traceNetworkServiceRegistryServer) Find(in *registry.NetworkServiceQuery, s registry.NetworkServiceRegistry_FindServer) error { - operation := typeutils.GetFuncName(t.traced, "Find") - ctx, finish := withLog(s.Context(), operation) + operation := typeutils.GetFuncName(t.traced, methodNameFind) + ctx, finish := withLog(s.Context(), operation, methodNameFind) defer finish() s = &traceNetworkServiceRegistryFindServer{ @@ -154,8 +154,8 @@ func (t *traceNetworkServiceRegistryServer) Find(in *registry.NetworkServiceQuer } func (t *traceNetworkServiceRegistryServer) Unregister(ctx context.Context, in *registry.NetworkService) (*empty.Empty, error) { - operation := typeutils.GetFuncName(t.traced, "Unregister") - ctx, finish := withLog(ctx, operation) + operation := typeutils.GetFuncName(t.traced, methodNameUnregister) + ctx, finish := withLog(ctx, operation, methodNameUnregister) defer finish() logObjectTrace(ctx, "unregister", in) @@ -179,8 +179,8 @@ type traceNetworkServiceRegistryFindServer struct { } func (t *traceNetworkServiceRegistryFindServer) Send(nsResp *registry.NetworkServiceResponse) error { - operation := typeutils.GetFuncName(t.NetworkServiceRegistry_FindServer, "Send") - ctx, finish := withLog(t.Context(), operation) + operation := typeutils.GetFuncName(t.NetworkServiceRegistry_FindServer, methodNameSend) + ctx, finish := withLog(t.Context(), operation, methodNameSend) defer finish() logObjectTrace(ctx, "network service", nsResp.NetworkService) diff --git a/pkg/registry/core/trace/nse_registry.go b/pkg/registry/core/trace/nse_registry.go index 7fc6c9f19..fb97c132c 100644 --- a/pkg/registry/core/trace/nse_registry.go +++ b/pkg/registry/core/trace/nse_registry.go @@ -43,9 +43,8 @@ type traceNetworkServiceEndpointRegistryFindClient struct { } func (t *traceNetworkServiceEndpointRegistryFindClient) Recv() (*registry.NetworkServiceEndpointResponse, error) { - operation := typeutils.GetFuncName(t.NetworkServiceEndpointRegistry_FindClient, "Recv") - - ctx, finish := withLog(t.Context(), operation) + operation := typeutils.GetFuncName(t.NetworkServiceEndpointRegistry_FindClient, methodNameRecv) + ctx, finish := withLog(t.Context(), operation, methodNameRecv) defer finish() s := streamcontext.NetworkServiceEndpointRegistryFindClient(ctx, t.NetworkServiceEndpointRegistry_FindClient) @@ -65,8 +64,8 @@ func (t *traceNetworkServiceEndpointRegistryFindClient) Recv() (*registry.Networ } func (t *traceNetworkServiceEndpointRegistryClient) Register(ctx context.Context, in *registry.NetworkServiceEndpoint, opts ...grpc.CallOption) (*registry.NetworkServiceEndpoint, error) { - operation := typeutils.GetFuncName(t.traced, "Register") - ctx, finish := withLog(ctx, operation) + operation := typeutils.GetFuncName(t.traced, methodNameRegister) + ctx, finish := withLog(ctx, operation, methodNameRegister) defer finish() logObjectTrace(ctx, "register", in) @@ -78,8 +77,8 @@ func (t *traceNetworkServiceEndpointRegistryClient) Register(ctx context.Context return rv, nil } func (t *traceNetworkServiceEndpointRegistryClient) Find(ctx context.Context, in *registry.NetworkServiceEndpointQuery, opts ...grpc.CallOption) (registry.NetworkServiceEndpointRegistry_FindClient, error) { - operation := typeutils.GetFuncName(t.traced, "Find") - ctx, finish := withLog(ctx, operation) + operation := typeutils.GetFuncName(t.traced, methodNameFind) + ctx, finish := withLog(ctx, operation, methodNameFind) defer finish() logObjectTrace(ctx, "find", in) @@ -95,8 +94,8 @@ func (t *traceNetworkServiceEndpointRegistryClient) Find(ctx context.Context, in } func (t *traceNetworkServiceEndpointRegistryClient) Unregister(ctx context.Context, in *registry.NetworkServiceEndpoint, opts ...grpc.CallOption) (*empty.Empty, error) { - operation := typeutils.GetFuncName(t.traced, "Unregister") - ctx, finish := withLog(ctx, operation) + operation := typeutils.GetFuncName(t.traced, methodNameUnregister) + ctx, finish := withLog(ctx, operation, methodNameUnregister) defer finish() logObjectTrace(ctx, "unregister", in) @@ -120,8 +119,8 @@ type traceNetworkServiceEndpointRegistryServer struct { } func (t *traceNetworkServiceEndpointRegistryServer) Register(ctx context.Context, in *registry.NetworkServiceEndpoint) (*registry.NetworkServiceEndpoint, error) { - operation := typeutils.GetFuncName(t.traced, "Register") - ctx, finish := withLog(ctx, operation) + operation := typeutils.GetFuncName(t.traced, methodNameRegister) + ctx, finish := withLog(ctx, operation, methodNameRegister) defer finish() logObjectTrace(ctx, "register", in) @@ -135,8 +134,8 @@ func (t *traceNetworkServiceEndpointRegistryServer) Register(ctx context.Context } func (t *traceNetworkServiceEndpointRegistryServer) Find(in *registry.NetworkServiceEndpointQuery, s registry.NetworkServiceEndpointRegistry_FindServer) error { - operation := typeutils.GetFuncName(t.traced, "Find") - ctx, finish := withLog(s.Context(), operation) + operation := typeutils.GetFuncName(t.traced, methodNameFind) + ctx, finish := withLog(s.Context(), operation, methodNameFind) defer finish() s = &traceNetworkServiceEndpointRegistryFindServer{ @@ -155,8 +154,8 @@ func (t *traceNetworkServiceEndpointRegistryServer) Find(in *registry.NetworkSer } func (t *traceNetworkServiceEndpointRegistryServer) Unregister(ctx context.Context, in *registry.NetworkServiceEndpoint) (*empty.Empty, error) { - operation := typeutils.GetFuncName(t.traced, "Unregister") - ctx, finish := withLog(ctx, operation) + operation := typeutils.GetFuncName(t.traced, methodNameUnregister) + ctx, finish := withLog(ctx, operation, methodNameUnregister) defer finish() logObjectTrace(ctx, "unregister", in) @@ -180,8 +179,8 @@ type traceNetworkServiceEndpointRegistryFindServer struct { } func (t *traceNetworkServiceEndpointRegistryFindServer) Send(nseResp *registry.NetworkServiceEndpointResponse) error { - operation := typeutils.GetFuncName(t.NetworkServiceEndpointRegistry_FindServer, "Send") - ctx, finish := withLog(t.Context(), operation) + operation := typeutils.GetFuncName(t.NetworkServiceEndpointRegistry_FindServer, methodNameSend) + ctx, finish := withLog(t.Context(), operation, methodNameSend) defer finish() logObjectTrace(ctx, "network service endpoint", nseResp.NetworkServiceEndpoint) diff --git a/pkg/tools/dnsutils/trace/context.go b/pkg/tools/dnsutils/trace/context.go index c99c7c48b..197576f01 100644 --- a/pkg/tools/dnsutils/trace/context.go +++ b/pkg/tools/dnsutils/trace/context.go @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2022 Cisco Systems, Inc. +// Copyright (c) 2020-2023 Cisco Systems, Inc. // // SPDX-License-Identifier: Apache-2.0 // @@ -39,14 +39,16 @@ type traceInfo struct { ResponseMsg *dns.Msg } -func withLog(parent context.Context, operation, messageID string) (c context.Context, f func()) { +func withLog(parent context.Context, operation, methodName, messageID string) (c context.Context, f func()) { if parent == nil { panic("cannot create context from nil parent") } if log.IsTracingEnabled() { - ctx, sLogger, span, sFinish := spanlogger.FromContext(parent, operation, map[string]interface{}{"type": loggedType, "id": messageID}) - ctx, lLogger, lFinish := logruslogger.FromSpan(ctx, span, operation, map[string]interface{}{"type": loggedType, "id": messageID}) + fields := []*log.Field{log.NewField("type", loggedType), log.NewField("id", messageID)} + + ctx, sLogger, span, sFinish := spanlogger.FromContext(parent, operation, methodName, fields) + ctx, lLogger, lFinish := logruslogger.FromSpan(ctx, span, operation, fields) return withTrace(log.WithLog(ctx, sLogger, lLogger)), func() { sFinish() lFinish() diff --git a/pkg/tools/dnsutils/trace/handler.go b/pkg/tools/dnsutils/trace/handler.go index 1c11bd2c5..d9381d0e6 100644 --- a/pkg/tools/dnsutils/trace/handler.go +++ b/pkg/tools/dnsutils/trace/handler.go @@ -1,4 +1,4 @@ -// Copyright (c) 2022 Cisco Systems, Inc. +// Copyright (c) 2022-2023 Cisco Systems, Inc. // // SPDX-License-Identifier: Apache-2.0 // @@ -42,8 +42,9 @@ func NewDNSHandler(traced dnsutils.Handler) dnsutils.Handler { } func (t *beginTraceHandler) ServeDNS(ctx context.Context, rw dns.ResponseWriter, m *dns.Msg) { - operation := typeutils.GetFuncName(t.traced, "ServeDNS") - ctx, finish := withLog(ctx, operation, strconv.Itoa(int(m.Id))) + methodName := "ServeDNS" + operation := typeutils.GetFuncName(t.traced, methodName) + ctx, finish := withLog(ctx, operation, methodName, strconv.Itoa(int(m.Id))) defer finish() logRequest(ctx, m, "message") diff --git a/pkg/tools/log/common.go b/pkg/tools/log/common.go new file mode 100644 index 000000000..0970460da --- /dev/null +++ b/pkg/tools/log/common.go @@ -0,0 +1,38 @@ +// Copyright (c) 2023 Cisco and/or its affiliates. +// +// SPDX-License-Identifier: Apache-2.0 +// +// 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 log + +// Field structure that is used for additional information in the logs +type Field struct { + k string + v interface{} +} + +// NewField creates Field +func NewField(k string, v interface{}) *Field { + return &Field{k, v} +} + +// Key returns key +func (f *Field) Key() string { + return f.k +} + +// Val returns value +func (f *Field) Val() interface{} { + return f.v +} diff --git a/pkg/tools/log/logruslogger/logruslogger.go b/pkg/tools/log/logruslogger/logruslogger.go index 96e421ba0..d66848fc7 100644 --- a/pkg/tools/log/logruslogger/logruslogger.go +++ b/pkg/tools/log/logruslogger/logruslogger.go @@ -1,5 +1,7 @@ // Copyright (c) 2021-2022 Doc.ai and/or its affiliates. // +// Copyright (c) 2023 Cisco and/or its affiliates. +// // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -271,21 +273,25 @@ func (s *traceLogger) getTraceInfo() string { // FromSpan - creates a new logruslogger from context, operation and span // and returns context with it, logger, and a function to defer func FromSpan( - ctx context.Context, span spanlogger.Span, operation string, fields map[string]interface{}) (context.Context, log.Logger, func()) { + ctx context.Context, span spanlogger.Span, operation string, fields []*log.Field) (context.Context, log.Logger, func()) { var info *traceCtxInfo ctx, info = withTraceInfo(ctx) localTraceInfo.Store(info.id, info) logger := log.L() if log.IsDefault(logger) { - entry := logrus.WithFields(fields) + fieldsMap := make(map[string]interface{}, len(fields)) + for _, field := range fields { + fieldsMap[field.Key()] = field.Val() + } + entry := logrus.WithFields(fieldsMap) entry.Logger.SetFormatter(newFormatter()) logger = &logrusLogger{ entry: entry, } } else { - for k, v := range fields { - logger = logger.WithField(k, v) + for _, field := range fields { + logger = logger.WithField(field.Key(), field.Val()) } } diff --git a/pkg/tools/log/spanlogger/span.go b/pkg/tools/log/spanlogger/span.go index 7bdc751c8..4e613750f 100644 --- a/pkg/tools/log/spanlogger/span.go +++ b/pkg/tools/log/spanlogger/span.go @@ -1,5 +1,7 @@ // Copyright (c) 2021-2022 Doc.ai and/or its affiliates. // +// Copyright (c) 2023 Cisco and/or its affiliates. +// // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -23,6 +25,8 @@ import ( "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" opentelemetry "go.opentelemetry.io/otel/trace" + + "github.com/networkservicemesh/sdk/pkg/tools/log" ) // Span - unified interface for opentelemetry spans @@ -37,6 +41,7 @@ type Span interface { // Opentelemetry span type otelSpan struct { + rootSpan opentelemetry.Span span opentelemetry.Span operationName string } @@ -74,17 +79,32 @@ func (otelsp *otelSpan) ToString() string { func (otelsp *otelSpan) Finish() { otelsp.span.End() + if otelsp.rootSpan != nil { + otelsp.rootSpan.End() + } } -func newOTELSpan(ctx context.Context, operationName string, additionalFields map[string]interface{}) (c context.Context, s Span) { - var add []attribute.KeyValue +func newOpentelemetrySpan(ctx context.Context, operationName, methodName string, additionalFields []*log.Field) (c context.Context, s Span) { + var attributes []attribute.KeyValue - for k, v := range additionalFields { - add = append(add, attribute.String(k, fmt.Sprint(v))) + for _, field := range additionalFields { + attributes = append(attributes, attribute.String(field.Key(), fmt.Sprint(field.Val()))) } + // Check if the current span is active + // If not (missing) - add a new root + var rootSpan opentelemetry.Span + if !opentelemetry.SpanFromContext(ctx).IsRecording() { + var rootSpanName string + for _, field := range additionalFields { + rootSpanName += fmt.Sprintf("[%s: %s] ", field.Key(), fmt.Sprint(field.Val())) + } + rootSpanName += fmt.Sprintf("[%s: %s]", "method", methodName) + ctx, rootSpan = otel.Tracer("").Start(ctx, rootSpanName, opentelemetry.WithNewRoot()) + rootSpan.SetAttributes(attributes...) + } ctx, span := otel.Tracer("").Start(ctx, operationName) - span.SetAttributes(add...) + span.SetAttributes(attributes...) - return ctx, &otelSpan{span: span, operationName: operationName} + return ctx, &otelSpan{rootSpan: rootSpan, span: span, operationName: operationName} } diff --git a/pkg/tools/log/spanlogger/spanlogger.go b/pkg/tools/log/spanlogger/spanlogger.go index d4aaf0e7b..64e3810f0 100644 --- a/pkg/tools/log/spanlogger/spanlogger.go +++ b/pkg/tools/log/spanlogger/spanlogger.go @@ -1,5 +1,7 @@ // Copyright (c) 2021-2022 Doc.ai and/or its affiliates. // +// Copyright (c) 2023 Cisco and/or its affiliates. +// // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -128,10 +130,10 @@ func (s *spanLogger) logf(level, format string, v ...interface{}) { } // FromContext - creates a new spanLogger from context and operation -func FromContext(ctx context.Context, operation string, fields map[string]interface{}) (context.Context, log.Logger, Span, func()) { +func FromContext(ctx context.Context, operation, methodName string, fields []*log.Field) (context.Context, log.Logger, Span, func()) { var span Span if opentelemetry.IsEnabled() { - ctx, span = newOTELSpan(ctx, operation, fields) + ctx, span = newOpentelemetrySpan(ctx, operation, methodName, fields) } newLog := &spanLogger{ span: span, diff --git a/pkg/tools/opentelemetry/opentelemetry.go b/pkg/tools/opentelemetry/opentelemetry.go index 639c2e349..868a35f6d 100644 --- a/pkg/tools/opentelemetry/opentelemetry.go +++ b/pkg/tools/opentelemetry/opentelemetry.go @@ -1,5 +1,7 @@ // Copyright (c) 2021-2022 Doc.ai and/or its affiliates. // +// Copyright (c) 2023 Cisco and/or its affiliates. +// // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -27,6 +29,7 @@ import ( "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/exporters/otlp/otlpmetric" "go.opentelemetry.io/otel/metric/global" + "go.opentelemetry.io/otel/propagation" controller "go.opentelemetry.io/otel/sdk/metric/controller/basic" processor "go.opentelemetry.io/otel/sdk/metric/processor/basic" "go.opentelemetry.io/otel/sdk/metric/selector/simple" @@ -109,6 +112,7 @@ func Init(ctx context.Context, spanExporter sdktrace.SpanExporter, metricExporte sdktrace.WithSpanProcessor(bsp), ) + otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{})) otel.SetTracerProvider(tracerProvider) o.tracerProvider = tracerProvider