From 0a2e4811a03db80bbe6fc19a7084432b81c5a570 Mon Sep 17 00:00:00 2001 From: kruskal <99559985+kruskall@users.noreply.github.com> Date: Wed, 13 Sep 2023 18:33:24 +0200 Subject: [PATCH 1/3] feat: use vtpool in modelprocessors --- model/modelprocessor/datastream.go | 2 +- model/modelprocessor/environment.go | 2 +- model/modelprocessor/hostname.go | 2 +- model/modelprocessor/nodename.go | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/model/modelprocessor/datastream.go b/model/modelprocessor/datastream.go index 46d50172..cda58603 100644 --- a/model/modelprocessor/datastream.go +++ b/model/modelprocessor/datastream.go @@ -50,7 +50,7 @@ type SetDataStream struct { func (s *SetDataStream) ProcessBatch(ctx context.Context, b *modelpb.Batch) error { for i := range *b { if (*b)[i].DataStream == nil { - (*b)[i].DataStream = &modelpb.DataStream{} + (*b)[i].DataStream = modelpb.DataStreamFromVTPool() } (*b)[i].DataStream.Namespace = s.Namespace if (*b)[i].DataStream.Type == "" || (*b)[i].DataStream.Dataset == "" { diff --git a/model/modelprocessor/environment.go b/model/modelprocessor/environment.go index 0600e0e7..014d5d84 100644 --- a/model/modelprocessor/environment.go +++ b/model/modelprocessor/environment.go @@ -36,7 +36,7 @@ func (s *SetDefaultServiceEnvironment) ProcessBatch(ctx context.Context, b *mode for i := range *b { event := (*b)[i] if event.Service == nil { - event.Service = &modelpb.Service{} + event.Service = modelpb.ServiceFromVTPool() } if event.Service.Environment == "" { event.Service.Environment = s.DefaultServiceEnvironment diff --git a/model/modelprocessor/hostname.go b/model/modelprocessor/hostname.go index be719f69..d523cdb5 100644 --- a/model/modelprocessor/hostname.go +++ b/model/modelprocessor/hostname.go @@ -40,7 +40,7 @@ func setHostHostname(event *modelpb.APMEvent) { switch { case event.GetKubernetes().GetNodeName() != "": if event.Host == nil { - event.Host = &modelpb.Host{} + event.Host = modelpb.HostFromVTPool() } // host.kubernetes.node.name is set: set host.hostname to its value. event.Host.Hostname = event.Kubernetes.NodeName diff --git a/model/modelprocessor/nodename.go b/model/modelprocessor/nodename.go index ba702d25..e46bb91f 100644 --- a/model/modelprocessor/nodename.go +++ b/model/modelprocessor/nodename.go @@ -52,10 +52,10 @@ func setServiceNodeName(event *modelpb.APMEvent) { return } if event.Service == nil { - event.Service = &modelpb.Service{} + event.Service = modelpb.ServiceFromVTPool() } if event.Service.Node == nil { - event.Service.Node = &modelpb.ServiceNode{} + event.Service.Node = modelpb.ServiceNodeFromVTPool() } event.Service.Node.Name = nodeName } From 66a62a898d335173071f240cd85c0703533e9304 Mon Sep 17 00:00:00 2001 From: kruskal <99559985+kruskall@users.noreply.github.com> Date: Wed, 13 Sep 2023 18:33:48 +0200 Subject: [PATCH 2/3] feat: migrate everything to vtpool --- .../modeldecoder/modeldecoderutil/http.go | 8 +- .../modeldecoderutil/keyvaluepb.go | 8 +- .../modeldecoder/modeldecoderutil/metrics.go | 4 +- .../internal/modeldecoder/rumv3/decoder.go | 262 ++++++--- .../internal/modeldecoder/v2/decoder.go | 536 ++++++++++++------ .../internal/modeldecoder/v2/metadata_test.go | 8 +- input/otlp/exceptions.go | 32 +- input/otlp/logs.go | 37 +- input/otlp/metadata.go | 231 ++++++-- input/otlp/metrics.go | 44 +- input/otlp/traces.go | 262 +++++---- 11 files changed, 926 insertions(+), 506 deletions(-) diff --git a/input/elasticapm/internal/modeldecoder/modeldecoderutil/http.go b/input/elasticapm/internal/modeldecoder/modeldecoderutil/http.go index 2233bf16..3d1138b1 100644 --- a/input/elasticapm/internal/modeldecoder/modeldecoderutil/http.go +++ b/input/elasticapm/internal/modeldecoder/modeldecoderutil/http.go @@ -51,10 +51,10 @@ func HTTPHeadersToModelpb(h http.Header) []*modelpb.HTTPHeader { } headers := make([]*modelpb.HTTPHeader, 0, len(h)) for k, v := range h { - headers = append(headers, &modelpb.HTTPHeader{ - Key: k, - Value: v, - }) + pbheader := modelpb.HTTPHeaderFromVTPool() + pbheader.Key = k + pbheader.Value = v + headers = append(headers, pbheader) } return headers } diff --git a/input/elasticapm/internal/modeldecoder/modeldecoderutil/keyvaluepb.go b/input/elasticapm/internal/modeldecoder/modeldecoderutil/keyvaluepb.go index ce4f8fd0..e95176e4 100644 --- a/input/elasticapm/internal/modeldecoder/modeldecoderutil/keyvaluepb.go +++ b/input/elasticapm/internal/modeldecoder/modeldecoderutil/keyvaluepb.go @@ -31,10 +31,10 @@ func ToKv(m map[string]any) []*modelpb.KeyValue { kv := []*modelpb.KeyValue{} for k, v := range m { value, _ := structpb.NewValue(v) - kv = append(kv, &modelpb.KeyValue{ - Key: k, - Value: value, - }) + pbkv := modelpb.KeyValueFromVTPool() + pbkv.Key = k + pbkv.Value = value + kv = append(kv, pbkv) } return kv diff --git a/input/elasticapm/internal/modeldecoder/modeldecoderutil/metrics.go b/input/elasticapm/internal/modeldecoder/modeldecoderutil/metrics.go index bfb0e445..d52cd680 100644 --- a/input/elasticapm/internal/modeldecoder/modeldecoderutil/metrics.go +++ b/input/elasticapm/internal/modeldecoder/modeldecoderutil/metrics.go @@ -42,13 +42,13 @@ func SetInternalMetrics(event *modelpb.APMEvent) bool { switch v.Name { case "span.self_time.count": if event.Span.SelfTime == nil { - event.Span.SelfTime = &modelpb.AggregatedDuration{} + event.Span.SelfTime = modelpb.AggregatedDurationFromVTPool() } event.Span.SelfTime.Count = uint64(v.Value) haveMetrics = true case "span.self_time.sum.us": if event.Span.SelfTime == nil { - event.Span.SelfTime = &modelpb.AggregatedDuration{} + event.Span.SelfTime = modelpb.AggregatedDurationFromVTPool() } event.Span.SelfTime.Sum = uint64(v.Value * 1000) haveMetrics = true diff --git a/input/elasticapm/internal/modeldecoder/rumv3/decoder.go b/input/elasticapm/internal/modeldecoder/rumv3/decoder.go index 1a17be27..2fbfe57a 100644 --- a/input/elasticapm/internal/modeldecoder/rumv3/decoder.go +++ b/input/elasticapm/internal/modeldecoder/rumv3/decoder.go @@ -129,10 +129,9 @@ func DecodeNestedTransaction(d decoder.Decoder, input *modeldecoder.Input, batch for _, m := range root.Transaction.Metricsets { event := input.Base.CloneVT() - event.Transaction = &modelpb.Transaction{ - Name: transaction.Transaction.Name, - Type: transaction.Transaction.Type, - } + event.Transaction = modelpb.TransactionFromVTPool() + event.Transaction.Name = transaction.Transaction.Name + event.Transaction.Type = transaction.Transaction.Type if mapToTransactionMetricsetModel(&m, event) { *batch = append(*batch, event) } @@ -142,7 +141,8 @@ func DecodeNestedTransaction(d decoder.Decoder, input *modeldecoder.Input, batch for _, s := range root.Transaction.Spans { event := input.Base.CloneVT() mapToSpanModel(&s, event) - event.Transaction = &modelpb.Transaction{Id: transaction.Transaction.Id} + event.Transaction = modelpb.TransactionFromVTPool() + event.Transaction.Id = transaction.Transaction.Id event.ParentId = transaction.GetTransaction().GetId() // may be overridden later event.Trace = transaction.Trace *batch = append(*batch, event) @@ -159,21 +159,27 @@ func DecodeNestedTransaction(d decoder.Decoder, input *modeldecoder.Input, batch } func mapToErrorModel(from *errorEvent, event *modelpb.APMEvent) { - out := &modelpb.Error{} + out := modelpb.ErrorFromVTPool() event.Error = out // overwrite metadata with event specific information if from.Context.Service.IsSet() { - event.Service = populateNil(event.Service) + if event.Service == nil { + event.Service = modelpb.ServiceFromVTPool() + } mapToServiceModel(from.Context.Service, event.Service) } if from.Context.Service.Agent.IsSet() { - event.Agent = populateNil(event.Agent) + if event.Agent == nil { + event.Agent = modelpb.AgentFromVTPool() + } mapToAgentModel(from.Context.Service.Agent, event.Agent) } overwriteUserInMetadataModel(from.Context.User, event) if from.Context.Request.Headers.IsSet() { - event.UserAgent = populateNil(event.UserAgent) + if event.UserAgent == nil { + event.UserAgent = modelpb.UserAgentFromVTPool() + } mapToUserAgentModel(from.Context.Request.Headers, event.UserAgent) } @@ -183,16 +189,24 @@ func mapToErrorModel(from *errorEvent, event *modelpb.APMEvent) { modeldecoderutil.MergeLabels(from.Context.Tags, event) } if from.Context.Request.IsSet() { - event.Http = populateNil(event.Http) - event.Http.Request = &modelpb.HTTPRequest{} + if event.Http == nil { + event.Http = modelpb.HTTPFromVTPool() + } + if event.Http.Request == nil { + event.Http.Request = modelpb.HTTPRequestFromVTPool() + } mapToRequestModel(from.Context.Request, event.Http.Request) if from.Context.Request.HTTPVersion.IsSet() { event.Http.Version = from.Context.Request.HTTPVersion.Val } } if from.Context.Response.IsSet() { - event.Http = populateNil(event.Http) - event.Http.Response = &modelpb.HTTPResponse{} + if event.Http == nil { + event.Http = modelpb.HTTPFromVTPool() + } + if event.Http.Response == nil { + event.Http.Response = modelpb.HTTPResponseFromVTPool() + } mapToResponseModel(from.Context.Response, event.Http.Response) } if from.Context.Page.IsSet() { @@ -200,8 +214,12 @@ func mapToErrorModel(from *errorEvent, event *modelpb.APMEvent) { event.Url = modelpb.ParseURL(from.Context.Page.URL.Val, "", "") } if from.Context.Page.Referer.IsSet() { - event.Http = populateNil(event.Http) - event.Http.Request = populateNil(event.Http.Request) + if event.Http == nil { + event.Http = modelpb.HTTPFromVTPool() + } + if event.Http.Request == nil { + event.Http.Request = modelpb.HTTPRequestFromVTPool() + } event.Http.Request.Referrer = from.Context.Page.Referer.Val } } @@ -213,14 +231,14 @@ func mapToErrorModel(from *errorEvent, event *modelpb.APMEvent) { out.Culprit = from.Culprit.Val } if from.Exception.IsSet() { - out.Exception = &modelpb.Exception{} + out.Exception = modelpb.ExceptionFromVTPool() mapToExceptionModel(from.Exception, out.Exception) } if from.ID.IsSet() { out.Id = from.ID.Val } if from.Log.IsSet() { - log := modelpb.ErrorLog{} + log := modelpb.ErrorLogFromVTPool() if from.Log.Level.IsSet() { log.Level = from.Log.Level.Val } @@ -240,7 +258,7 @@ func mapToErrorModel(from *errorEvent, event *modelpb.APMEvent) { log.Stacktrace = make([]*modelpb.StacktraceFrame, len(from.Log.Stacktrace)) mapToStracktraceModel(from.Log.Stacktrace, log.Stacktrace) } - out.Log = &log + out.Log = log } if from.ParentID.IsSet() { event.ParentId = from.ParentID.Val @@ -249,12 +267,11 @@ func mapToErrorModel(from *errorEvent, event *modelpb.APMEvent) { event.Timestamp = modelpb.FromTime(from.Timestamp.Val) } if from.TraceID.IsSet() { - event.Trace = &modelpb.Trace{ - Id: from.TraceID.Val, - } + event.Trace = modelpb.TraceFromVTPool() + event.Trace.Id = from.TraceID.Val } if from.Transaction.IsSet() { - event.Transaction = &modelpb.Transaction{} + event.Transaction = modelpb.TransactionFromVTPool() if from.Transaction.Sampled.IsSet() { event.Transaction.Sampled = from.Transaction.Sampled.Val } @@ -311,7 +328,9 @@ func mapToMetadataModel(m *metadata, out *modelpb.APMEvent) { // Service if m.Service.Agent.IsSet() { - out.Agent = populateNil(out.Agent) + if out.Agent == nil { + out.Agent = modelpb.AgentFromVTPool() + } if m.Service.Agent.Name.IsSet() { out.Agent.Name = m.Service.Agent.Name.Val } @@ -320,12 +339,16 @@ func mapToMetadataModel(m *metadata, out *modelpb.APMEvent) { } } if m.Service.IsSet() { - out.Service = populateNil(out.Service) + if out.Service == nil { + out.Service = modelpb.ServiceFromVTPool() + } if m.Service.Environment.IsSet() { out.Service.Environment = m.Service.Environment.Val } if m.Service.Framework.IsSet() { - out.Service.Framework = populateNil(out.Service.Framework) + if out.Service.Framework == nil { + out.Service.Framework = modelpb.FrameworkFromVTPool() + } if m.Service.Framework.Name.IsSet() { out.Service.Framework.Name = m.Service.Framework.Name.Val } @@ -334,7 +357,9 @@ func mapToMetadataModel(m *metadata, out *modelpb.APMEvent) { } } if m.Service.Language.IsSet() { - out.Service.Language = populateNil(out.Service.Language) + if out.Service.Language == nil { + out.Service.Language = modelpb.LanguageFromVTPool() + } if m.Service.Language.Name.IsSet() { out.Service.Language.Name = m.Service.Language.Name.Val } @@ -346,7 +371,9 @@ func mapToMetadataModel(m *metadata, out *modelpb.APMEvent) { out.Service.Name = m.Service.Name.Val } if m.Service.Runtime.IsSet() { - out.Service.Runtime = populateNil(out.Service.Runtime) + if out.Service.Runtime == nil { + out.Service.Runtime = modelpb.RuntimeFromVTPool() + } if m.Service.Runtime.Name.IsSet() { out.Service.Runtime.Name = m.Service.Runtime.Name.Val } @@ -361,7 +388,9 @@ func mapToMetadataModel(m *metadata, out *modelpb.APMEvent) { // User if m.User.IsSet() { - out.User = populateNil(out.User) + if out.User == nil { + out.User = modelpb.UserFromVTPool() + } if m.User.Domain.IsSet() { out.User.Domain = fmt.Sprint(m.User.Domain.Val) } @@ -378,17 +407,21 @@ func mapToMetadataModel(m *metadata, out *modelpb.APMEvent) { // Network if m.Network.Connection.Type.IsSet() { - out.Network = populateNil(out.Network) - out.Network.Connection = populateNil(out.Network.Connection) + if out.Network == nil { + out.Network = modelpb.NetworkFromVTPool() + } + if out.Network.Connection == nil { + out.Network.Connection = modelpb.NetworkConnectionFromVTPool() + } out.Network.Connection.Type = m.Network.Connection.Type.Val } } func mapToTransactionMetricsetModel(from *transactionMetricset, event *modelpb.APMEvent) bool { - event.Metricset = &modelpb.Metricset{} + event.Metricset = modelpb.MetricsetFromVTPool() if from.Span.IsSet() { - event.Span = &modelpb.Span{} + event.Span = modelpb.SpanFromVTPool() if from.Span.Subtype.IsSet() { event.Span.Subtype = from.Span.Subtype.Val } @@ -401,12 +434,16 @@ func mapToTransactionMetricsetModel(from *transactionMetricset, event *modelpb.A if from.Samples.IsSet() { if event.Span != nil { if value := from.Samples.SpanSelfTimeCount.Value; value.IsSet() { - event.Span.SelfTime = populateNil(event.Span.SelfTime) + if event.Span.SelfTime == nil { + event.Span.SelfTime = modelpb.AggregatedDurationFromVTPool() + } event.Span.SelfTime.Count = uint64(value.Val) ok = true } if value := from.Samples.SpanSelfTimeSum.Value; value.IsSet() { - event.Span.SelfTime = populateNil(event.Span.SelfTime) + if event.Span.SelfTime == nil { + event.Span.SelfTime = modelpb.AggregatedDurationFromVTPool() + } event.Span.SelfTime.Sum = uint64(value.Val * 1000) ok = true } @@ -453,7 +490,9 @@ func mapToServiceModel(from contextService, out *modelpb.Service) { out.Environment = from.Environment.Val } if from.Framework.IsSet() { - out.Framework = populateNil(out.Framework) + if out.Framework == nil { + out.Framework = modelpb.FrameworkFromVTPool() + } if from.Framework.Name.IsSet() { out.Framework.Name = from.Framework.Name.Val } @@ -462,7 +501,9 @@ func mapToServiceModel(from contextService, out *modelpb.Service) { } } if from.Language.IsSet() { - out.Language = populateNil(out.Language) + if out.Language == nil { + out.Language = modelpb.LanguageFromVTPool() + } if from.Language.Name.IsSet() { out.Language.Name = from.Language.Name.Val } @@ -475,7 +516,9 @@ func mapToServiceModel(from contextService, out *modelpb.Service) { out.Version = from.Version.Val } if from.Runtime.IsSet() { - out.Runtime = populateNil(out.Runtime) + if out.Runtime == nil { + out.Runtime = modelpb.RuntimeFromVTPool() + } if from.Runtime.Name.IsSet() { out.Runtime.Name = from.Runtime.Name.Val } @@ -495,7 +538,8 @@ func mapToAgentModel(from contextServiceAgent, out *modelpb.Agent) { } func mapToSpanModel(from *span, event *modelpb.APMEvent) { - out := &modelpb.Span{Type: "unknown"} + out := modelpb.SpanFromVTPool() + out.Type = "unknown" event.Span = out // map span specific data @@ -521,16 +565,20 @@ func mapToSpanModel(from *span, event *modelpb.APMEvent) { } if from.Context.Destination.Address.IsSet() || from.Context.Destination.Port.IsSet() { if from.Context.Destination.Address.IsSet() { - event.Destination = populateNil(event.Destination) + if event.Destination == nil { + event.Destination = modelpb.DestinationFromVTPool() + } event.Destination.Address = from.Context.Destination.Address.Val } if from.Context.Destination.Port.IsSet() { - event.Destination = populateNil(event.Destination) + if event.Destination == nil { + event.Destination = modelpb.DestinationFromVTPool() + } event.Destination.Port = uint32(from.Context.Destination.Port.Val) } } if from.Context.Destination.Service.IsSet() { - service := modelpb.DestinationService{} + service := modelpb.DestinationServiceFromVTPool() if from.Context.Destination.Service.Name.IsSet() { service.Name = from.Context.Destination.Service.Name.Val } @@ -540,26 +588,36 @@ func mapToSpanModel(from *span, event *modelpb.APMEvent) { if from.Context.Destination.Service.Type.IsSet() { service.Type = from.Context.Destination.Service.Type.Val } - out.DestinationService = &service + out.DestinationService = service } if from.Context.HTTP.IsSet() { var response modelpb.HTTPResponse if from.Context.HTTP.Method.IsSet() { - event.Http = populateNil(event.Http) - event.Http.Request = &modelpb.HTTPRequest{} + if event.Http == nil { + event.Http = modelpb.HTTPFromVTPool() + } + if event.Http.Request == nil { + event.Http.Request = modelpb.HTTPRequestFromVTPool() + } event.Http.Request.Method = from.Context.HTTP.Method.Val } if from.Context.HTTP.StatusCode.IsSet() { - event.Http = populateNil(event.Http) + if event.Http == nil { + event.Http = modelpb.HTTPFromVTPool() + } event.Http.Response = &response event.Http.Response.StatusCode = uint32(from.Context.HTTP.StatusCode.Val) } if from.Context.HTTP.URL.IsSet() { - event.Url = populateNil(event.Url) + if event.Url == nil { + event.Url = modelpb.URLFromVTPool() + } event.Url.Original = from.Context.HTTP.URL.Val } if from.Context.HTTP.Response.IsSet() { - event.Http = populateNil(event.Http) + if event.Http == nil { + event.Http = modelpb.HTTPFromVTPool() + } event.Http.Response = &response if from.Context.HTTP.Response.DecodedBodySize.IsSet() { val := uint64(from.Context.HTTP.Response.DecodedBodySize.Val) @@ -577,7 +635,9 @@ func mapToSpanModel(from *span, event *modelpb.APMEvent) { } if from.Context.Service.IsSet() { if from.Context.Service.Name.IsSet() { - event.Service = populateNil(event.Service) + if event.Service == nil { + event.Service = modelpb.ServiceFromVTPool() + } event.Service.Name = from.Context.Service.Name.Val } } @@ -585,7 +645,9 @@ func mapToSpanModel(from *span, event *modelpb.APMEvent) { modeldecoderutil.MergeLabels(from.Context.Tags, event) } if from.Duration.IsSet() { - event.Event = populateNil(event.Event) + if event.Event == nil { + event.Event = modelpb.EventFromVTPool() + } event.Event.Duration = uint64(from.Duration.Val * float64(time.Millisecond)) } if from.ID.IsSet() { @@ -594,7 +656,9 @@ func mapToSpanModel(from *span, event *modelpb.APMEvent) { if from.Name.IsSet() { out.Name = from.Name.Val } - event.Event = populateNil(event.Event) + if event.Event == nil { + event.Event = modelpb.EventFromVTPool() + } if from.Outcome.IsSet() { event.Event.Outcome = from.Outcome.Val } else { @@ -669,21 +733,28 @@ func mapToStracktraceModel(from []stacktraceFrame, out []*modelpb.StacktraceFram } func mapToTransactionModel(from *transaction, event *modelpb.APMEvent) { - out := &modelpb.Transaction{Type: "unknown"} + out := modelpb.TransactionFromVTPool() + out.Type = "unknown" event.Transaction = out // overwrite metadata with event specific information if from.Context.Service.IsSet() { - event.Service = populateNil(event.Service) + if event.Service == nil { + event.Service = modelpb.ServiceFromVTPool() + } mapToServiceModel(from.Context.Service, event.Service) } if from.Context.Service.Agent.IsSet() { - event.Agent = populateNil(event.Agent) + if event.Agent == nil { + event.Agent = modelpb.AgentFromVTPool() + } mapToAgentModel(from.Context.Service.Agent, event.Agent) } overwriteUserInMetadataModel(from.Context.User, event) if from.Context.Request.Headers.IsSet() { - event.UserAgent = populateNil(event.UserAgent) + if event.UserAgent == nil { + event.UserAgent = modelpb.UserAgentFromVTPool() + } mapToUserAgentModel(from.Context.Request.Headers, event.UserAgent) } @@ -696,16 +767,20 @@ func mapToTransactionModel(from *transaction, event *modelpb.APMEvent) { modeldecoderutil.MergeLabels(from.Context.Tags, event) } if from.Context.Request.IsSet() { - event.Http = populateNil(event.Http) - event.Http.Request = &modelpb.HTTPRequest{} + if event.Http == nil { + event.Http = modelpb.HTTPFromVTPool() + } + event.Http.Request = modelpb.HTTPRequestFromVTPool() mapToRequestModel(from.Context.Request, event.Http.Request) if from.Context.Request.HTTPVersion.IsSet() { event.Http.Version = from.Context.Request.HTTPVersion.Val } } if from.Context.Response.IsSet() { - event.Http = populateNil(event.Http) - event.Http.Response = &modelpb.HTTPResponse{} + if event.Http == nil { + event.Http = modelpb.HTTPFromVTPool() + } + event.Http.Response = modelpb.HTTPResponseFromVTPool() mapToResponseModel(from.Context.Response, event.Http.Response) } if from.Context.Page.IsSet() { @@ -713,14 +788,20 @@ func mapToTransactionModel(from *transaction, event *modelpb.APMEvent) { event.Url = modelpb.ParseURL(from.Context.Page.URL.Val, "", "") } if from.Context.Page.Referer.IsSet() { - event.Http = populateNil(event.Http) - event.Http.Request = populateNil(event.Http.Request) + if event.Http == nil { + event.Http = modelpb.HTTPFromVTPool() + } + if event.Http.Request == nil { + event.Http.Request = modelpb.HTTPRequestFromVTPool() + } event.Http.Request.Referrer = from.Context.Page.Referer.Val } } } if from.Duration.IsSet() { - event.Event = populateNil(event.Event) + if event.Event == nil { + event.Event = modelpb.EventFromVTPool() + } event.Event.Duration = uint64(from.Duration.Val * float64(time.Millisecond)) } if from.ID.IsSet() { @@ -729,15 +810,17 @@ func mapToTransactionModel(from *transaction, event *modelpb.APMEvent) { if from.Marks.IsSet() { out.Marks = make(map[string]*modelpb.TransactionMark, len(from.Marks.Events)) for event, val := range from.Marks.Events { - out.Marks[event] = &modelpb.TransactionMark{ - Measurements: val.Measurements, - } + tm := modelpb.TransactionMarkFromVTPool() + tm.Measurements = val.Measurements + out.Marks[event] = tm } } if from.Name.IsSet() { out.Name = from.Name.Val } - event.Event = populateNil(event.Event) + if event.Event == nil { + event.Event = modelpb.EventFromVTPool() + } if from.Outcome.IsSet() { event.Event.Outcome = from.Outcome.Val } else { @@ -772,36 +855,39 @@ func mapToTransactionModel(from *transaction, event *modelpb.APMEvent) { out.RepresentativeCount = 1 } if from.Session.ID.IsSet() { - event.Session = &modelpb.Session{ - Id: from.Session.ID.Val, - Sequence: uint64(from.Session.Sequence.Val), - } + event.Session = modelpb.SessionFromVTPool() + event.Session.Id = from.Session.ID.Val + event.Session.Sequence = uint64(from.Session.Sequence.Val) } if from.SpanCount.Dropped.IsSet() { - out.SpanCount = populateNil(out.SpanCount) + if out.SpanCount == nil { + out.SpanCount = modelpb.SpanCountFromVTPool() + } dropped := uint32(from.SpanCount.Dropped.Val) out.SpanCount.Dropped = &dropped } if from.SpanCount.Started.IsSet() { - out.SpanCount = populateNil(out.SpanCount) + if out.SpanCount == nil { + out.SpanCount = modelpb.SpanCountFromVTPool() + } started := uint32(from.SpanCount.Started.Val) out.SpanCount.Started = &started } if from.TraceID.IsSet() { - event.Trace = &modelpb.Trace{ - Id: from.TraceID.Val, + if event.Trace == nil { + event.Trace = modelpb.TraceFromVTPool() } + event.Trace.Id = from.TraceID.Val } if from.Type.IsSet() { out.Type = from.Type.Val } if from.UserExperience.IsSet() { - out.UserExperience = &modelpb.UserExperience{ - CumulativeLayoutShift: -1, - FirstInputDelay: -1, - TotalBlockingTime: -1, - LongTask: nil, - } + out.UserExperience = modelpb.UserExperienceFromVTPool() + out.UserExperience.CumulativeLayoutShift = -1 + out.UserExperience.FirstInputDelay = -1 + out.UserExperience.TotalBlockingTime = -1 + out.UserExperience.LongTask = nil if from.UserExperience.CumulativeLayoutShift.IsSet() { out.UserExperience.CumulativeLayoutShift = from.UserExperience.CumulativeLayoutShift.Val } @@ -812,11 +898,10 @@ func mapToTransactionModel(from *transaction, event *modelpb.APMEvent) { out.UserExperience.TotalBlockingTime = from.UserExperience.TotalBlockingTime.Val } if from.UserExperience.Longtask.IsSet() { - out.UserExperience.LongTask = &modelpb.LongtaskMetrics{ - Count: uint64(from.UserExperience.Longtask.Count.Val), - Sum: from.UserExperience.Longtask.Sum.Val, - Max: from.UserExperience.Longtask.Max.Val, - } + out.UserExperience.LongTask = modelpb.LongtaskMetricsFromVTPool() + out.UserExperience.LongTask.Count = uint64(from.UserExperience.Longtask.Count.Val) + out.UserExperience.LongTask.Sum = from.UserExperience.Longtask.Sum.Val + out.UserExperience.LongTask.Max = from.UserExperience.Longtask.Max.Val } } } @@ -835,7 +920,7 @@ func overwriteUserInMetadataModel(from user, out *modelpb.APMEvent) { if !from.Domain.IsSet() && !from.ID.IsSet() && !from.Email.IsSet() && !from.Name.IsSet() { return } - out.User = &modelpb.User{} + out.User = modelpb.UserFromVTPool() if from.Domain.IsSet() { out.User.Domain = fmt.Sprint(from.Domain.Val) } @@ -849,10 +934,3 @@ func overwriteUserInMetadataModel(from user, out *modelpb.APMEvent) { out.User.Name = from.Name.Val } } - -func populateNil[T any](a *T) *T { - if a == nil { - return new(T) - } - return a -} diff --git a/input/elasticapm/internal/modeldecoder/v2/decoder.go b/input/elasticapm/internal/modeldecoder/v2/decoder.go index b575f631..9151254a 100644 --- a/input/elasticapm/internal/modeldecoder/v2/decoder.go +++ b/input/elasticapm/internal/modeldecoder/v2/decoder.go @@ -338,7 +338,7 @@ func mapToDroppedSpansModel(from []transactionDroppedSpanStats, tx *modelpb.Tran } func mapToCloudModel(from contextCloud, cloud *modelpb.Cloud) { - cloudOrigin := &modelpb.CloudOrigin{} + cloudOrigin := modelpb.CloudOriginFromVTPool() if from.Origin.Account.ID.IsSet() { cloudOrigin.AccountId = from.Origin.Account.ID.Val } @@ -359,31 +359,40 @@ func mapToClientModel(from contextRequest, source **modelpb.Source, client **mod if (*source).GetIp() == nil { ip, port := netutil.SplitAddrPort(from.Socket.RemoteAddress.Val) if ip.IsValid() { - *source = populateNil(*source) + if *source == nil { + *source = modelpb.SourceFromVTPool() + } (*source).Ip, (*source).Port = modelpb.Addr2IP(ip), uint32(port) } } if (*client).GetIp() == nil { if (*source).GetIp() != nil { - *client = populateNil(*client) + if *client == nil { + *client = modelpb.ClientFromVTPool() + } (*client).Ip = (*source).Ip } if addr, port := netutil.ClientAddrFromHeaders(from.Headers.Val); addr.IsValid() { if (*source).GetIp() != nil { - (*source).Nat = &modelpb.NAT{Ip: (*source).Ip} + (*source).Nat = modelpb.NATFromVTPool() + (*source).Nat.Ip = (*source).Ip + } + if *client == nil { + *client = modelpb.ClientFromVTPool() } - *client = populateNil(*client) ip := modelpb.Addr2IP(addr) (*client).Ip, (*client).Port = ip, uint32(port) - *source = populateNil(*source) + if *source == nil { + *source = modelpb.SourceFromVTPool() + } (*source).Ip, (*source).Port = ip, uint32(port) } } } func mapToErrorModel(from *errorEvent, event *modelpb.APMEvent) { - out := &modelpb.Error{} + out := modelpb.ErrorFromVTPool() event.Error = out // overwrite metadata with event specific information @@ -400,20 +409,26 @@ func mapToErrorModel(from *errorEvent, event *modelpb.APMEvent) { modeldecoderutil.MergeLabels(from.Context.Tags, event) } if from.Context.Request.IsSet() { - event.Http = populateNil(event.Http) - event.Http.Request = &modelpb.HTTPRequest{} + if event.Http == nil { + event.Http = modelpb.HTTPFromVTPool() + } + event.Http.Request = modelpb.HTTPRequestFromVTPool() mapToRequestModel(from.Context.Request, event.Http.Request) if from.Context.Request.HTTPVersion.IsSet() { event.Http.Version = from.Context.Request.HTTPVersion.Val } } if from.Context.Response.IsSet() { - event.Http = populateNil(event.Http) - event.Http.Response = &modelpb.HTTPResponse{} + if event.Http == nil { + event.Http = modelpb.HTTPFromVTPool() + } + event.Http.Response = modelpb.HTTPResponseFromVTPool() mapToResponseModel(from.Context.Response, event.Http.Response) } if from.Context.Request.URL.IsSet() { - event.Url = populateNil(event.Url) + if event.Url == nil { + event.Url = modelpb.URLFromVTPool() + } mapToRequestURLModel(from.Context.Request.URL, event.Url) } if from.Context.Page.IsSet() { @@ -421,8 +436,12 @@ func mapToErrorModel(from *errorEvent, event *modelpb.APMEvent) { event.Url = modelpb.ParseURL(from.Context.Page.URL.Val, "", "") } if from.Context.Page.Referer.IsSet() { - event.Http = populateNil(event.Http) - event.Http.Request = populateNil(event.Http.Request) + if event.Http == nil { + event.Http = modelpb.HTTPFromVTPool() + } + if event.Http.Request == nil { + event.Http.Request = modelpb.HTTPRequestFromVTPool() + } if event.Http.Request.Referrer == "" { event.Http.Request.Referrer = from.Context.Page.Referer.Val } @@ -436,7 +455,7 @@ func mapToErrorModel(from *errorEvent, event *modelpb.APMEvent) { out.Culprit = from.Culprit.Val } if from.Exception.IsSet() { - out.Exception = &modelpb.Exception{} + out.Exception = modelpb.ExceptionFromVTPool() mapToExceptionModel(from.Exception, out.Exception) } if from.ID.IsSet() { @@ -469,18 +488,16 @@ func mapToErrorModel(from *errorEvent, event *modelpb.APMEvent) { event.Timestamp = modelpb.FromTime(from.Timestamp.Val) } if from.TraceID.IsSet() { - event.Trace = &modelpb.Trace{ - Id: from.TraceID.Val, - } + event.Trace = modelpb.TraceFromVTPool() + event.Trace.Id = from.TraceID.Val } if from.TransactionID.IsSet() || from.Transaction.IsSet() { - event.Transaction = &modelpb.Transaction{} + event.Transaction = modelpb.TransactionFromVTPool() } if from.TransactionID.IsSet() { event.Transaction.Id = from.TransactionID.Val - event.Span = &modelpb.Span{ - Id: from.TransactionID.Val, - } + event.Span = modelpb.SpanFromVTPool() + event.Span.Id = from.TransactionID.Val } if from.Transaction.IsSet() { if from.Transaction.Sampled.IsSet() { @@ -531,7 +548,9 @@ func mapToExceptionModel(from errorException, out *modelpb.Exception) { func mapToMetadataModel(from *metadata, out *modelpb.APMEvent) { // Cloud if from.Cloud.IsSet() { - out.Cloud = populateNil(out.Cloud) + if out.Cloud == nil { + out.Cloud = modelpb.CloudFromVTPool() + } if from.Cloud.Account.ID.IsSet() { out.Cloud.AccountId = from.Cloud.Account.ID.Val } @@ -574,26 +593,36 @@ func mapToMetadataModel(from *metadata, out *modelpb.APMEvent) { // Process if len(from.Process.Argv) > 0 { - out.Process = populateNil(out.Process) + if out.Process == nil { + out.Process = modelpb.ProcessFromVTPool() + } out.Process.Argv = append(out.Process.Argv[:0], from.Process.Argv...) } if from.Process.Pid.IsSet() { - out.Process = populateNil(out.Process) + if out.Process == nil { + out.Process = modelpb.ProcessFromVTPool() + } out.Process.Pid = uint32(from.Process.Pid.Val) } if from.Process.Ppid.IsSet() { var pid = uint32(from.Process.Ppid.Val) - out.Process = populateNil(out.Process) + if out.Process == nil { + out.Process = modelpb.ProcessFromVTPool() + } out.Process.Ppid = pid } if from.Process.Title.IsSet() { - out.Process = populateNil(out.Process) + if out.Process == nil { + out.Process = modelpb.ProcessFromVTPool() + } out.Process.Title = from.Process.Title.Val } // Service if from.Service.Agent.IsSet() { - out.Agent = populateNil(out.Agent) + if out.Agent == nil { + out.Agent = modelpb.AgentFromVTPool() + } if from.Service.Agent.ActivationMethod.IsSet() { out.Agent.ActivationMethod = from.Service.Agent.ActivationMethod.Val } @@ -608,12 +637,16 @@ func mapToMetadataModel(from *metadata, out *modelpb.APMEvent) { } } if from.Service.IsSet() { - out.Service = populateNil(out.Service) + if out.Service == nil { + out.Service = modelpb.ServiceFromVTPool() + } if from.Service.Environment.IsSet() { out.Service.Environment = from.Service.Environment.Val } if from.Service.Framework.IsSet() { - out.Service.Framework = populateNil(out.Service.Framework) + if out.Service.Framework == nil { + out.Service.Framework = modelpb.FrameworkFromVTPool() + } if from.Service.Framework.Name.IsSet() { out.Service.Framework.Name = from.Service.Framework.Name.Val } @@ -622,7 +655,9 @@ func mapToMetadataModel(from *metadata, out *modelpb.APMEvent) { } } if from.Service.Language.IsSet() { - out.Service.Language = populateNil(out.Service.Language) + if out.Service.Language == nil { + out.Service.Language = modelpb.LanguageFromVTPool() + } if from.Service.Language.Name.IsSet() { out.Service.Language.Name = from.Service.Language.Name.Val } @@ -634,11 +669,15 @@ func mapToMetadataModel(from *metadata, out *modelpb.APMEvent) { out.Service.Name = from.Service.Name.Val } if from.Service.Node.Name.IsSet() { - out.Service.Node = populateNil(out.Service.Node) + if out.Service.Node == nil { + out.Service.Node = modelpb.ServiceNodeFromVTPool() + } out.Service.Node.Name = from.Service.Node.Name.Val } if from.Service.Runtime.IsSet() { - out.Service.Runtime = populateNil(out.Service.Runtime) + if out.Service.Runtime == nil { + out.Service.Runtime = modelpb.RuntimeFromVTPool() + } if from.Service.Runtime.Name.IsSet() { out.Service.Runtime.Name = from.Service.Runtime.Name.Val } @@ -653,76 +692,111 @@ func mapToMetadataModel(from *metadata, out *modelpb.APMEvent) { // System if from.System.Architecture.IsSet() { - out.Host = populateNil(out.Host) + if out.Host == nil { + out.Host = modelpb.HostFromVTPool() + } out.Host.Architecture = from.System.Architecture.Val } if from.System.ConfiguredHostname.IsSet() { - out.Host = populateNil(out.Host) + if out.Host == nil { + out.Host = modelpb.HostFromVTPool() + } out.Host.Name = from.System.ConfiguredHostname.Val } if from.System.Container.ID.IsSet() { - out.Container = populateNil(out.Container) + if out.Container == nil { + out.Container = modelpb.ContainerFromVTPool() + } out.Container.Id = from.System.Container.ID.Val } if from.System.DetectedHostname.IsSet() { - out.Host = populateNil(out.Host) + if out.Host == nil { + out.Host = modelpb.HostFromVTPool() + } out.Host.Hostname = from.System.DetectedHostname.Val } if !from.System.ConfiguredHostname.IsSet() && !from.System.DetectedHostname.IsSet() && from.System.DeprecatedHostname.IsSet() { - out.Host = populateNil(out.Host) + if out.Host == nil { + out.Host = modelpb.HostFromVTPool() + } out.Host.Hostname = from.System.DeprecatedHostname.Val } if from.System.Kubernetes.Namespace.IsSet() { - out.Kubernetes = populateNil(out.Kubernetes) + if out.Kubernetes == nil { + out.Kubernetes = modelpb.KubernetesFromVTPool() + } out.Kubernetes.Namespace = from.System.Kubernetes.Namespace.Val } if from.System.Kubernetes.Node.Name.IsSet() { - out.Kubernetes = populateNil(out.Kubernetes) + if out.Kubernetes == nil { + out.Kubernetes = modelpb.KubernetesFromVTPool() + } out.Kubernetes.NodeName = from.System.Kubernetes.Node.Name.Val } if from.System.Kubernetes.Pod.Name.IsSet() { - out.Kubernetes = populateNil(out.Kubernetes) + if out.Kubernetes == nil { + out.Kubernetes = modelpb.KubernetesFromVTPool() + } out.Kubernetes.PodName = from.System.Kubernetes.Pod.Name.Val } if from.System.Kubernetes.Pod.UID.IsSet() { - out.Kubernetes = populateNil(out.Kubernetes) + if out.Kubernetes == nil { + out.Kubernetes = modelpb.KubernetesFromVTPool() + } out.Kubernetes.PodUid = from.System.Kubernetes.Pod.UID.Val } if from.System.Platform.IsSet() { - out.Host = populateNil(out.Host) - out.Host.Os = populateNil(out.Host.Os) + if out.Host == nil { + out.Host = modelpb.HostFromVTPool() + } + if out.Host.Os == nil { + out.Host.Os = modelpb.OSFromVTPool() + } out.Host.Os.Platform = from.System.Platform.Val } // User if from.User.Domain.IsSet() { - out.User = populateNil(out.User) + if out.User == nil { + out.User = modelpb.UserFromVTPool() + } out.User.Domain = fmt.Sprint(from.User.Domain.Val) } if from.User.ID.IsSet() { - out.User = populateNil(out.User) + if out.User == nil { + out.User = modelpb.UserFromVTPool() + } out.User.Id = fmt.Sprint(from.User.ID.Val) } if from.User.Email.IsSet() { - out.User = populateNil(out.User) + if out.User == nil { + out.User = modelpb.UserFromVTPool() + } out.User.Email = from.User.Email.Val } if from.User.Name.IsSet() { - out.User = populateNil(out.User) + if out.User == nil { + out.User = modelpb.UserFromVTPool() + } out.User.Name = from.User.Name.Val } // Network if from.Network.Connection.Type.IsSet() { - out.Network = populateNil(out.Network) - out.Network.Connection = populateNil(out.Network.Connection) + if out.Network == nil { + out.Network = modelpb.NetworkFromVTPool() + } + if out.Network.Connection == nil { + out.Network.Connection = modelpb.NetworkConnectionFromVTPool() + } out.Network.Connection.Type = from.Network.Connection.Type.Val } } func mapToMetricsetModel(from *metricset, event *modelpb.APMEvent) bool { - event.Metricset = &modelpb.Metricset{Name: "app"} + event.Metricset = modelpb.MetricsetFromVTPool() + event.Metricset.Name = "app" if !from.Timestamp.Val.IsZero() { event.Timestamp = modelpb.FromTime(from.Timestamp.Val) @@ -743,19 +817,18 @@ func mapToMetricsetModel(from *metricset, event *modelpb.APMEvent) bool { copy(counts, sample.Counts) } if len(counts) != 0 || len(values) != 0 { - histogram = &modelpb.Histogram{ - Values: values, - Counts: counts, - } + histogram = modelpb.HistogramFromVTPool() + histogram.Values = values + histogram.Counts = counts } - samples = append(samples, &modelpb.MetricsetSample{ - Type: metricTypeText[sample.Type.Val], - Name: name, - Unit: sample.Unit.Val, - Value: sample.Value.Val, - Histogram: histogram, - }) + ms := modelpb.MetricsetSampleFromVTPool() + ms.Type = metricTypeText[sample.Type.Val] + ms.Name = name + ms.Unit = sample.Unit.Val + ms.Value = sample.Value.Val + ms.Histogram = histogram + samples = append(samples, ms) } event.Metricset.Samples = samples } @@ -765,7 +838,7 @@ func mapToMetricsetModel(from *metricset, event *modelpb.APMEvent) bool { } if from.Span.IsSet() { - event.Span = &modelpb.Span{} + event.Span = modelpb.SpanFromVTPool() if from.Span.Subtype.IsSet() { event.Span.Subtype = from.Span.Subtype.Val } @@ -776,7 +849,7 @@ func mapToMetricsetModel(from *metricset, event *modelpb.APMEvent) bool { ok := true if from.Transaction.IsSet() { - event.Transaction = &modelpb.Transaction{} + event.Transaction = modelpb.TransactionFromVTPool() if from.Transaction.Name.IsSet() { event.Transaction.Name = from.Transaction.Name.Val } @@ -790,13 +863,17 @@ func mapToMetricsetModel(from *metricset, event *modelpb.APMEvent) bool { } if from.Service.Name.IsSet() { - event.Service = populateNil(event.Service) + if event.Service == nil { + event.Service = modelpb.ServiceFromVTPool() + } event.Service.Name = from.Service.Name.Val event.Service.Version = from.Service.Version.Val } if from.FAAS.IsSet() { - event.Faas = populateNil(event.Faas) + if event.Faas == nil { + event.Faas = modelpb.FaasFromVTPool() + } mapToFAASModel(from.FAAS, event.Faas) } @@ -883,13 +960,17 @@ func mapToResponseModel(from contextResponse, out *modelpb.HTTPResponse) { func mapToServiceModel(from contextService, outPtr **modelpb.Service) { var out *modelpb.Service - *outPtr = populateNil(*outPtr) + if *outPtr == nil { + *outPtr = modelpb.ServiceFromVTPool() + } out = *outPtr if from.Environment.IsSet() { out.Environment = from.Environment.Val } if from.Framework.IsSet() { - out.Framework = populateNil(out.Framework) + if out.Framework == nil { + out.Framework = modelpb.FrameworkFromVTPool() + } if from.Framework.Name.IsSet() { out.Framework.Name = from.Framework.Name.Val } @@ -898,7 +979,9 @@ func mapToServiceModel(from contextService, outPtr **modelpb.Service) { } } if from.Language.IsSet() { - out.Language = populateNil(out.Language) + if out.Language == nil { + out.Language = modelpb.LanguageFromVTPool() + } if from.Language.Name.IsSet() { out.Language.Name = from.Language.Name.Val } @@ -911,11 +994,15 @@ func mapToServiceModel(from contextService, outPtr **modelpb.Service) { out.Version = from.Version.Val } if from.Node.Name.IsSet() { - out.Node = populateNil(out.Node) + if out.Node == nil { + out.Node = modelpb.ServiceNodeFromVTPool() + } out.Node.Name = from.Node.Name.Val } if from.Runtime.IsSet() { - out.Runtime = populateNil(out.Runtime) + if out.Runtime == nil { + out.Runtime = modelpb.RuntimeFromVTPool() + } if from.Runtime.Name.IsSet() { out.Runtime.Name = from.Runtime.Name.Val } @@ -924,7 +1011,7 @@ func mapToServiceModel(from contextService, outPtr **modelpb.Service) { } } if from.Origin.IsSet() { - outOrigin := &modelpb.ServiceOrigin{} + outOrigin := modelpb.ServiceOriginFromVTPool() if from.Origin.ID.IsSet() { outOrigin.Id = from.Origin.ID.Val } @@ -937,7 +1024,7 @@ func mapToServiceModel(from contextService, outPtr **modelpb.Service) { out.Origin = outOrigin } if from.Target.IsSet() { - outTarget := &modelpb.ServiceTarget{} + outTarget := modelpb.ServiceTargetFromVTPool() if from.Target.Name.IsSet() { outTarget.Name = from.Target.Name.Val } @@ -949,7 +1036,9 @@ func mapToServiceModel(from contextService, outPtr **modelpb.Service) { } func mapToAgentModel(from contextServiceAgent, out **modelpb.Agent) { - *out = populateNil(*out) + if *out == nil { + *out = modelpb.AgentFromVTPool() + } if from.Name.IsSet() { (*out).Name = from.Name.Val } @@ -962,7 +1051,7 @@ func mapToAgentModel(from contextServiceAgent, out **modelpb.Agent) { } func mapToSpanModel(from *span, event *modelpb.APMEvent) { - out := &modelpb.Span{} + out := modelpb.SpanFromVTPool() event.Span = out // map span specific data @@ -1026,11 +1115,15 @@ func mapToSpanModel(from *span, event *modelpb.APMEvent) { } if from.Context.Destination.Address.IsSet() || from.Context.Destination.Port.IsSet() { if from.Context.Destination.Address.IsSet() { - event.Destination = populateNil(event.Destination) + if event.Destination == nil { + event.Destination = modelpb.DestinationFromVTPool() + } event.Destination.Address = from.Context.Destination.Address.Val } if from.Context.Destination.Port.IsSet() { - event.Destination = populateNil(event.Destination) + if event.Destination == nil { + event.Destination = modelpb.DestinationFromVTPool() + } event.Destination.Port = uint32(from.Context.Destination.Port.Val) } } @@ -1049,18 +1142,28 @@ func mapToSpanModel(from *span, event *modelpb.APMEvent) { } if from.Context.HTTP.IsSet() { if from.Context.HTTP.Method.IsSet() { - event.Http = populateNil(event.Http) - event.Http.Request = populateNil(event.Http.Request) + if event.Http == nil { + event.Http = modelpb.HTTPFromVTPool() + } + if event.Http.Request == nil { + event.Http.Request = modelpb.HTTPRequestFromVTPool() + } event.Http.Request.Method = from.Context.HTTP.Method.Val } if from.Context.HTTP.Request.ID.IsSet() { - event.Http = populateNil(event.Http) - event.Http.Request = populateNil(event.Http.Request) + if event.Http == nil { + event.Http = modelpb.HTTPFromVTPool() + } + if event.Http.Request == nil { + event.Http.Request = modelpb.HTTPRequestFromVTPool() + } event.Http.Request.Id = from.Context.HTTP.Request.ID.Val } if from.Context.HTTP.Response.IsSet() { - event.Http = populateNil(event.Http) - response := modelpb.HTTPResponse{} + if event.Http == nil { + event.Http = modelpb.HTTPFromVTPool() + } + response := modelpb.HTTPResponseFromVTPool() if from.Context.HTTP.Response.DecodedBodySize.IsSet() { val := uint64(from.Context.HTTP.Response.DecodedBodySize.Val) response.DecodedBodySize = &val @@ -1079,15 +1182,21 @@ func mapToSpanModel(from *span, event *modelpb.APMEvent) { val := uint64(from.Context.HTTP.Response.TransferSize.Val) response.TransferSize = &val } - event.Http.Response = &response + event.Http.Response = response } if from.Context.HTTP.StatusCode.IsSet() { - event.Http = populateNil(event.Http) - event.Http.Response = populateNil(event.Http.Response) + if event.Http == nil { + event.Http = modelpb.HTTPFromVTPool() + } + if event.Http.Response == nil { + event.Http.Response = modelpb.HTTPResponseFromVTPool() + } event.Http.Response.StatusCode = uint32(from.Context.HTTP.StatusCode.Val) } if from.Context.HTTP.URL.IsSet() { - event.Url = populateNil(event.Url) + if event.Url == nil { + event.Url = modelpb.URLFromVTPool() + } event.Url.Original = from.Context.HTTP.URL.Val } } @@ -1116,7 +1225,9 @@ func mapToSpanModel(from *span, event *modelpb.APMEvent) { mapToAgentModel(from.Context.Service.Agent, &event.Agent) } if !from.Context.Service.Target.Type.IsSet() && from.Context.Destination.Service.Resource.IsSet() { - event.Service = populateNil(event.Service) + if event.Service == nil { + event.Service = modelpb.ServiceFromVTPool() + } outTarget := targetFromDestinationResource(from.Context.Destination.Service.Resource.Val) event.Service.Target = &outTarget } @@ -1124,7 +1235,9 @@ func mapToSpanModel(from *span, event *modelpb.APMEvent) { modeldecoderutil.MergeLabels(from.Context.Tags, event) } if from.Duration.IsSet() { - event.Event = populateNil(event.Event) + if event.Event == nil { + event.Event = modelpb.EventFromVTPool() + } event.Event.Duration = uint64(from.Duration.Val * float64(time.Millisecond)) } if from.ID.IsSet() { @@ -1133,7 +1246,9 @@ func mapToSpanModel(from *span, event *modelpb.APMEvent) { if from.Name.IsSet() { out.Name = from.Name.Val } - event.Event = populateNil(event.Event) + if event.Event == nil { + event.Event = modelpb.EventFromVTPool() + } if from.Outcome.IsSet() { event.Event.Outcome = from.Outcome.Val } else { @@ -1180,12 +1295,12 @@ func mapToSpanModel(from *span, event *modelpb.APMEvent) { event.Timestamp += uint64(float64(time.Millisecond) * from.Start.Val) } if from.TraceID.IsSet() { - event.Trace = &modelpb.Trace{ - Id: from.TraceID.Val, - } + event.Trace = modelpb.TraceFromVTPool() + event.Trace.Id = from.TraceID.Val } if from.TransactionID.IsSet() { - event.Transaction = &modelpb.Transaction{Id: from.TransactionID.Val} + event.Transaction = modelpb.TransactionFromVTPool() + event.Transaction.Id = from.TransactionID.Val } if from.OTel.IsSet() { mapOTelAttributesSpan(from.OTel, event) @@ -1247,7 +1362,7 @@ func mapToStracktraceModel(from []stacktraceFrame, out []*modelpb.StacktraceFram } func mapToTransactionModel(from *transaction, event *modelpb.APMEvent) { - out := &modelpb.Transaction{} + out := modelpb.TransactionFromVTPool() event.Transaction = out // overwrite metadata with event specific information @@ -1257,11 +1372,15 @@ func mapToTransactionModel(from *transaction, event *modelpb.APMEvent) { mapToUserAgentModel(from.Context.Request.Headers, &event.UserAgent) mapToClientModel(from.Context.Request, &event.Source, &event.Client) if from.FAAS.IsSet() { - event.Faas = populateNil(event.Faas) + if event.Faas == nil { + event.Faas = modelpb.FaasFromVTPool() + } mapToFAASModel(from.FAAS, event.Faas) } if from.Context.Cloud.IsSet() { - event.Cloud = populateNil(event.Cloud) + if event.Cloud == nil { + event.Cloud = modelpb.CloudFromVTPool() + } mapToCloudModel(from.Context.Cloud, event.Cloud) } mapToDroppedSpansModel(from.DroppedSpanStats, event.Transaction) @@ -1276,7 +1395,7 @@ func mapToTransactionModel(from *transaction, event *modelpb.APMEvent) { modeldecoderutil.MergeLabels(from.Context.Tags, event) } if from.Context.Message.IsSet() { - out.Message = &modelpb.Message{} + out.Message = modelpb.MessageFromVTPool() if from.Context.Message.Age.IsSet() { val := uint64(from.Context.Message.Age.Milliseconds.Val) out.Message.AgeMillis = &val @@ -1295,20 +1414,26 @@ func mapToTransactionModel(from *transaction, event *modelpb.APMEvent) { } } if from.Context.Request.IsSet() { - event.Http = populateNil(event.Http) - event.Http.Request = &modelpb.HTTPRequest{} + if event.Http == nil { + event.Http = modelpb.HTTPFromVTPool() + } + event.Http.Request = modelpb.HTTPRequestFromVTPool() mapToRequestModel(from.Context.Request, event.Http.Request) if from.Context.Request.HTTPVersion.IsSet() { event.Http.Version = from.Context.Request.HTTPVersion.Val } } if from.Context.Request.URL.IsSet() { - event.Url = populateNil(event.Url) + if event.Url == nil { + event.Url = modelpb.URLFromVTPool() + } mapToRequestURLModel(from.Context.Request.URL, event.Url) } if from.Context.Response.IsSet() { - event.Http = populateNil(event.Http) - event.Http.Response = &modelpb.HTTPResponse{} + if event.Http == nil { + event.Http = modelpb.HTTPFromVTPool() + } + event.Http.Response = modelpb.HTTPResponseFromVTPool() mapToResponseModel(from.Context.Response, event.Http.Response) } if from.Context.Page.IsSet() { @@ -1316,8 +1441,12 @@ func mapToTransactionModel(from *transaction, event *modelpb.APMEvent) { event.Url = modelpb.ParseURL(from.Context.Page.URL.Val, "", "") } if from.Context.Page.Referer.IsSet() { - event.Http = populateNil(event.Http) - event.Http.Request = populateNil(event.Http.Request) + if event.Http == nil { + event.Http = modelpb.HTTPFromVTPool() + } + if event.Http.Request == nil { + event.Http.Request = modelpb.HTTPRequestFromVTPool() + } if event.Http.Request.Referrer == "" { event.Http.Request.Referrer = from.Context.Page.Referer.Val } @@ -1325,27 +1454,30 @@ func mapToTransactionModel(from *transaction, event *modelpb.APMEvent) { } } if from.Duration.IsSet() { - event.Event = populateNil(event.Event) + if event.Event == nil { + event.Event = modelpb.EventFromVTPool() + } event.Event.Duration = uint64(from.Duration.Val * float64(time.Millisecond)) } if from.ID.IsSet() { out.Id = from.ID.Val - event.Span = &modelpb.Span{ - Id: from.ID.Val, - } + event.Span = modelpb.SpanFromVTPool() + event.Span.Id = from.ID.Val } if from.Marks.IsSet() { out.Marks = make(map[string]*modelpb.TransactionMark, len(from.Marks.Events)) for event, val := range from.Marks.Events { - out.Marks[event] = &modelpb.TransactionMark{ - Measurements: val.Measurements, - } + tm := modelpb.TransactionMarkFromVTPool() + tm.Measurements = val.Measurements + out.Marks[event] = tm } } if from.Name.IsSet() { out.Name = from.Name.Val } - event.Event = populateNil(event.Event) + if event.Event == nil { + event.Event = modelpb.EventFromVTPool() + } if from.Outcome.IsSet() { event.Event.Outcome = from.Outcome.Val } else { @@ -1379,18 +1511,21 @@ func mapToTransactionModel(from *transaction, event *modelpb.APMEvent) { out.RepresentativeCount = 1 } if from.Session.ID.IsSet() { - event.Session = &modelpb.Session{ - Id: from.Session.ID.Val, - Sequence: uint64(from.Session.Sequence.Val), - } + event.Session = modelpb.SessionFromVTPool() + event.Session.Id = from.Session.ID.Val + event.Session.Sequence = uint64(from.Session.Sequence.Val) } if from.SpanCount.Dropped.IsSet() { - out.SpanCount = populateNil(out.SpanCount) + if out.SpanCount == nil { + out.SpanCount = modelpb.SpanCountFromVTPool() + } dropped := uint32(from.SpanCount.Dropped.Val) out.SpanCount.Dropped = &dropped } if from.SpanCount.Started.IsSet() { - out.SpanCount = populateNil(out.SpanCount) + if out.SpanCount == nil { + out.SpanCount = modelpb.SpanCountFromVTPool() + } started := uint32(from.SpanCount.Started.Val) out.SpanCount.Started = &started } @@ -1398,20 +1533,18 @@ func mapToTransactionModel(from *transaction, event *modelpb.APMEvent) { event.Timestamp = modelpb.FromTime(from.Timestamp.Val) } if from.TraceID.IsSet() { - event.Trace = &modelpb.Trace{ - Id: from.TraceID.Val, - } + event.Trace = modelpb.TraceFromVTPool() + event.Trace.Id = from.TraceID.Val } if from.Type.IsSet() { out.Type = from.Type.Val } if from.UserExperience.IsSet() { - out.UserExperience = &modelpb.UserExperience{ - CumulativeLayoutShift: -1, - FirstInputDelay: -1, - TotalBlockingTime: -1, - LongTask: nil, - } + out.UserExperience = modelpb.UserExperienceFromVTPool() + out.UserExperience.CumulativeLayoutShift = -1 + out.UserExperience.FirstInputDelay = -1 + out.UserExperience.TotalBlockingTime = -1 + out.UserExperience.LongTask = nil if from.UserExperience.CumulativeLayoutShift.IsSet() { out.UserExperience.CumulativeLayoutShift = from.UserExperience.CumulativeLayoutShift.Val } @@ -1423,21 +1556,24 @@ func mapToTransactionModel(from *transaction, event *modelpb.APMEvent) { out.UserExperience.TotalBlockingTime = from.UserExperience.TotalBlockingTime.Val } if from.UserExperience.Longtask.IsSet() { - out.UserExperience.LongTask = &modelpb.LongtaskMetrics{ - Count: uint64(from.UserExperience.Longtask.Count.Val), - Sum: from.UserExperience.Longtask.Sum.Val, - Max: from.UserExperience.Longtask.Max.Val, - } + out.UserExperience.LongTask = modelpb.LongtaskMetricsFromVTPool() + out.UserExperience.LongTask.Count = uint64(from.UserExperience.Longtask.Count.Val) + out.UserExperience.LongTask.Sum = from.UserExperience.Longtask.Sum.Val + out.UserExperience.LongTask.Max = from.UserExperience.Longtask.Max.Val } } if from.OTel.IsSet() { - event.Span = populateNil(event.Span) + if event.Span == nil { + event.Span = modelpb.SpanFromVTPool() + } mapOTelAttributesTransaction(from.OTel, event) } if len(from.Links) > 0 { - event.Span = populateNil(event.Span) + if event.Span == nil { + event.Span = modelpb.SpanFromVTPool() + } mapSpanLinks(from.Links, &event.Span.Links) } if out.Type == "" { @@ -1447,98 +1583,133 @@ func mapToTransactionModel(from *transaction, event *modelpb.APMEvent) { func mapToLogModel(from *log, event *modelpb.APMEvent) { if from.FAAS.IsSet() { - event.Faas = populateNil(event.Faas) + if event.Faas == nil { + event.Faas = modelpb.FaasFromVTPool() + } mapToFAASModel(from.FAAS, event.Faas) } if !from.Timestamp.Val.IsZero() { event.Timestamp = modelpb.FromTime(from.Timestamp.Val) } if from.TraceID.IsSet() { - event.Trace = &modelpb.Trace{ - Id: from.TraceID.Val, - } + event.Trace = modelpb.TraceFromVTPool() + event.Trace.Id = from.TraceID.Val } if from.TransactionID.IsSet() { - event.Transaction = &modelpb.Transaction{ - Id: from.TransactionID.Val, - } - event.Span = &modelpb.Span{ - Id: from.TransactionID.Val, - } + event.Transaction = modelpb.TransactionFromVTPool() + event.Transaction.Id = from.TransactionID.Val + event.Span = modelpb.SpanFromVTPool() + event.Span.Id = from.TransactionID.Val } if from.SpanID.IsSet() { - event.Span = &modelpb.Span{ - Id: from.SpanID.Val, - } + event.Span = modelpb.SpanFromVTPool() + event.Span.Id = from.SpanID.Val } if from.Message.IsSet() { event.Message = from.Message.Val } if from.Level.IsSet() { - event.Log = populateNil(event.Log) + if event.Log == nil { + event.Log = modelpb.LogFromVTPool() + } event.Log.Level = from.Level.Val } if from.Logger.IsSet() { - event.Log = populateNil(event.Log) + if event.Log == nil { + event.Log = modelpb.LogFromVTPool() + } event.Log.Logger = from.Logger.Val } if from.OriginFunction.IsSet() { - event.Log = populateNil(event.Log) - event.Log.Origin = populateNil(event.Log.Origin) + if event.Log == nil { + event.Log = modelpb.LogFromVTPool() + } + if event.Log.Origin == nil { + event.Log.Origin = modelpb.LogOriginFromVTPool() + } event.Log.Origin.FunctionName = from.OriginFunction.Val } if from.OriginFileLine.IsSet() { - event.Log = populateNil(event.Log) - event.Log.Origin = populateNil(event.Log.Origin) - event.Log.Origin.File = populateNil(event.Log.Origin.File) + if event.Log == nil { + event.Log = modelpb.LogFromVTPool() + } + if event.Log.Origin == nil { + event.Log.Origin = modelpb.LogOriginFromVTPool() + } + if event.Log.Origin.File == nil { + event.Log.Origin.File = modelpb.LogOriginFileFromVTPool() + } event.Log.Origin.File.Line = uint32(from.OriginFileLine.Val) } if from.OriginFileName.IsSet() { - event.Log = populateNil(event.Log) - event.Log.Origin = populateNil(event.Log.Origin) - event.Log.Origin.File = populateNil(event.Log.Origin.File) + if event.Log == nil { + event.Log = modelpb.LogFromVTPool() + } + if event.Log.Origin == nil { + event.Log.Origin = modelpb.LogOriginFromVTPool() + } + if event.Log.Origin.File == nil { + event.Log.Origin.File = modelpb.LogOriginFileFromVTPool() + } event.Log.Origin.File.Name = from.OriginFileName.Val } if from.ErrorType.IsSet() || from.ErrorMessage.IsSet() || from.ErrorStacktrace.IsSet() { - event.Error = &modelpb.Error{ - Message: from.ErrorMessage.Val, - Type: from.ErrorType.Val, - StackTrace: from.ErrorStacktrace.Val, - } + event.Error = modelpb.ErrorFromVTPool() + event.Error.Message = from.ErrorMessage.Val + event.Error.Type = from.ErrorType.Val + event.Error.StackTrace = from.ErrorStacktrace.Val } if from.ServiceName.IsSet() { - event.Service = populateNil(event.Service) + if event.Service == nil { + event.Service = modelpb.ServiceFromVTPool() + } event.Service.Name = from.ServiceName.Val } if from.ServiceVersion.IsSet() { - event.Service = populateNil(event.Service) + if event.Service == nil { + event.Service = modelpb.ServiceFromVTPool() + } event.Service.Version = from.ServiceVersion.Val } if from.ServiceEnvironment.IsSet() { - event.Service = populateNil(event.Service) + if event.Service == nil { + event.Service = modelpb.ServiceFromVTPool() + } event.Service.Environment = from.ServiceEnvironment.Val } if from.ServiceNodeName.IsSet() { - event.Service = populateNil(event.Service) - event.Service.Node = populateNil(event.Service.Node) + if event.Service == nil { + event.Service = modelpb.ServiceFromVTPool() + } + if event.Service.Node == nil { + event.Service.Node = modelpb.ServiceNodeFromVTPool() + } event.Service.Node.Name = from.ServiceNodeName.Val } if from.ProcessThreadName.IsSet() { - event.Process = populateNil(event.Process) - event.Process.Thread = populateNil(event.Process.Thread) + if event.Process == nil { + event.Process = modelpb.ProcessFromVTPool() + } + if event.Process.Thread == nil { + event.Process.Thread = modelpb.ProcessThreadFromVTPool() + } event.Process.Thread.Name = from.ProcessThreadName.Val } if from.EventDataset.IsSet() { - event.Event = populateNil(event.Event) + if event.Event == nil { + event.Event = modelpb.EventFromVTPool() + } event.Event.Dataset = from.EventDataset.Val } if len(from.Labels) > 0 { modeldecoderutil.MergeLabels(from.Labels, event) } if event.Error == nil { - event.Event = populateNil(event.Event) + if event.Event == nil { + event.Event = modelpb.EventFromVTPool() + } event.Event.Kind = "event" } } @@ -1623,7 +1794,9 @@ func mapToUserAgentModel(from nullable.HTTPHeader, out **modelpb.UserAgent) { // overwrite userAgent information if available if from.IsSet() { if h := from.Val.Values(textproto.CanonicalMIMEHeaderKey("User-Agent")); len(h) > 0 { - *out = populateNil(*out) + if *out == nil { + *out = modelpb.UserAgentFromVTPool() + } (*out).Original = strings.Join(h, ", ") } } @@ -1636,7 +1809,7 @@ func overwriteUserInMetadataModel(from user, out *modelpb.APMEvent) { if !from.Domain.IsSet() && !from.ID.IsSet() && !from.Email.IsSet() && !from.Name.IsSet() { return } - out.User = &modelpb.User{} + out.User = modelpb.UserFromVTPool() if from.Domain.IsSet() { out.User.Domain = fmt.Sprint(from.Domain.Val) } @@ -1714,10 +1887,10 @@ func isOTelDoubleAttribute(k string) bool { func mapSpanLinks(from []spanLink, out *[]*modelpb.SpanLink) { *out = make([]*modelpb.SpanLink, len(from)) for i, link := range from { - (*out)[i] = &modelpb.SpanLink{ - SpanId: link.SpanID.Val, - TraceId: link.TraceID.Val, - } + sl := modelpb.SpanLinkFromVTPool() + sl.SpanId = link.SpanID.Val + sl.TraceId = link.TraceID.Val + (*out)[i] = sl } } @@ -1732,10 +1905,3 @@ func targetFromDestinationResource(res string) (target modelpb.ServiceTarget) { } return } - -func populateNil[T any](a *T) *T { - if a == nil { - return new(T) - } - return a -} diff --git a/input/elasticapm/internal/modeldecoder/v2/metadata_test.go b/input/elasticapm/internal/modeldecoder/v2/metadata_test.go index a8390ea3..b298e191 100644 --- a/input/elasticapm/internal/modeldecoder/v2/metadata_test.go +++ b/input/elasticapm/internal/modeldecoder/v2/metadata_test.go @@ -297,9 +297,13 @@ func TestDecodeMapToMetadataModel(t *testing.T) { modeldecodertest.SetStructValues(&input, otherVal) mapToMetadataModel(&input, &out2) out2.Host.Ip = []*modelpb.IP{defaultVal.IP} - out2.Client = populateNil(out2.Client) + if out2.Client == nil { + out2.Client = &modelpb.Client{} + } out2.Client.Ip = defaultVal.IP - out2.Source = populateNil(out2.Source) + if out2.Source == nil { + out2.Source = &modelpb.Source{} + } out2.Source.Ip = defaultVal.IP modeldecodertest.AssertStructValues(t, &out2, isMetadataException, otherVal) modeldecodertest.AssertStructValues(t, &out1, isMetadataException, defaultVal) diff --git a/input/otlp/exceptions.go b/input/otlp/exceptions.go index 7e209d8c..1fd28856 100644 --- a/input/otlp/exceptions.go +++ b/input/otlp/exceptions.go @@ -60,13 +60,11 @@ func convertOpenTelemetryExceptionSpanEvent( exceptionMessage = "[EMPTY]" } exceptionHandled := !exceptionEscaped - exceptionError := modelpb.Error{ - Exception: &modelpb.Exception{ - Message: exceptionMessage, - Type: exceptionType, - Handled: &exceptionHandled, - }, - } + exceptionError := modelpb.ErrorFromVTPool() + exceptionError.Exception = modelpb.ExceptionFromVTPool() + exceptionError.Exception.Message = exceptionMessage + exceptionError.Exception.Type = exceptionType + exceptionError.Exception.Handled = &exceptionHandled // TODO(axw) replace github.com/gofrs/uuid, not worth having the dependency just for this. if id, err := uuid.NewV4(); err == nil { exceptionError.Id = id.String() @@ -79,7 +77,7 @@ func convertOpenTelemetryExceptionSpanEvent( exceptionError.StackTrace = exceptionStacktrace } } - return &exceptionError + return exceptionError } func setExceptionStacktrace(s, language string, out *modelpb.Exception) error { @@ -153,7 +151,7 @@ func setJavaExceptionStacktrace(s string, out *modelpb.Exception) error { // "Caused by:" lines are at the same level of indentation // as the enclosing exception. current.Cause = make([]*modelpb.Exception, 1) - current.Cause[0] = &modelpb.Exception{} + current.Cause[0] = modelpb.ExceptionFromVTPool() current.enclosing = current.Exception current.Exception = current.Cause[0] current.Exception.Handled = current.enclosing.Handled @@ -166,7 +164,7 @@ func setJavaExceptionStacktrace(s string, out *modelpb.Exception) error { // enclosing exception; we just account for the indentation here. stack = append(stack, current) current.enclosing = current.Exception - current.Exception = &modelpb.Exception{} + current.Exception = modelpb.ExceptionFromVTPool() current.indent = indent default: return fmt.Errorf("unexpected line %q", line) @@ -204,13 +202,13 @@ func parseJavaStacktraceFrame(s string, out *modelpb.Exception) error { lineno = &un } } - out.Stacktrace = append(out.Stacktrace, &modelpb.StacktraceFrame{ - Module: module, - Classname: classname, - Function: function, - Filename: file, - Lineno: lineno, - }) + sf := modelpb.StacktraceFrameFromVTPool() + sf.Module = module + sf.Classname = classname + sf.Function = function + sf.Filename = file + sf.Lineno = lineno + out.Stacktrace = append(out.Stacktrace, sf) return nil } diff --git a/input/otlp/logs.go b/input/otlp/logs.go index ff081166..ca9709ce 100644 --- a/input/otlp/logs.go +++ b/input/otlp/logs.go @@ -66,19 +66,17 @@ func (c *Consumer) ConsumeLogs(ctx context.Context, logs plog.Logs) error { func (c *Consumer) convertResourceLogs(resourceLogs plog.ResourceLogs, receiveTimestamp time.Time, out *modelpb.Batch) { var timeDelta time.Duration resource := resourceLogs.Resource() - baseEvent := modelpb.APMEvent{ - Event: &modelpb.Event{ - Received: modelpb.FromTime(receiveTimestamp), - }, - } - translateResourceMetadata(resource, &baseEvent) + baseEvent := modelpb.APMEventFromVTPool() + baseEvent.Event = modelpb.EventFromVTPool() + baseEvent.Event.Received = modelpb.FromTime(receiveTimestamp) + translateResourceMetadata(resource, baseEvent) if exportTimestamp, ok := exportTimestamp(resource); ok { timeDelta = receiveTimestamp.Sub(exportTimestamp) } scopeLogs := resourceLogs.ScopeLogs() for i := 0; i < scopeLogs.Len(); i++ { - c.convertInstrumentationLibraryLogs(scopeLogs.At(i), &baseEvent, timeDelta, out) + c.convertInstrumentationLibraryLogs(scopeLogs.At(i), baseEvent, timeDelta, out) } } @@ -103,9 +101,13 @@ func (c *Consumer) convertLogRecord( event := baseEvent.CloneVT() initEventLabels(event) event.Timestamp = modelpb.FromTime(record.Timestamp().AsTime().Add(timeDelta)) - event.Event = populateNil(event.Event) + if event.Event == nil { + event.Event = modelpb.EventFromVTPool() + } event.Event.Severity = uint64(record.SeverityNumber()) - event.Log = populateNil(event.Log) + if event.Log == nil { + event.Log = modelpb.LogFromVTPool() + } event.Log.Level = record.SeverityText() if body := record.Body(); body.Type() != pcommon.ValueTypeEmpty { event.Message = body.AsString() @@ -114,12 +116,15 @@ func (c *Consumer) convertLogRecord( } } if traceID := record.TraceID(); !traceID.IsEmpty() { - event.Trace = &modelpb.Trace{ - Id: hex.EncodeToString(traceID[:]), + if event.Trace == nil { + event.Trace = modelpb.TraceFromVTPool() } + event.Trace.Id = hex.EncodeToString(traceID[:]) } if spanID := record.SpanID(); !spanID.IsEmpty() { - event.Span = populateNil(event.Span) + if event.Span == nil { + event.Span = modelpb.SpanFromVTPool() + } event.Span.Id = hex.EncodeToString(spanID[:]) } attrs := record.Attributes() @@ -145,7 +150,9 @@ func (c *Consumer) convertLogRecord( case "event.domain": eventDomain = v.Str() case "session.id": - event.Session = populateNil(event.Session) + if event.Session == nil { + event.Session = modelpb.SessionFromVTPool() + } event.Session.Id = v.Str() default: setLabel(replaceDots(k), event, ifaceAttributeValue(v)) @@ -167,7 +174,9 @@ func (c *Consumer) convertLogRecord( if eventDomain == "device" && eventName != "" { event.Event.Category = "device" if eventName == "crash" { - event.Error = populateNil(event.Error) + if event.Error == nil { + event.Error = modelpb.ErrorFromVTPool() + } event.Error.Type = "crash" } else { event.Event.Kind = "event" diff --git a/input/otlp/metadata.go b/input/otlp/metadata.go index 1538623c..c0a57e04 100644 --- a/input/otlp/metadata.go +++ b/input/otlp/metadata.go @@ -43,146 +43,242 @@ func translateResourceMetadata(resource pcommon.Resource, out *modelpb.APMEvent) switch k { // service.* case semconv.AttributeServiceName: - out.Service = populateNil(out.Service) + if out.Service == nil { + out.Service = modelpb.ServiceFromVTPool() + } out.Service.Name = cleanServiceName(v.Str()) case semconv.AttributeServiceVersion: - out.Service = populateNil(out.Service) + if out.Service == nil { + out.Service = modelpb.ServiceFromVTPool() + } out.Service.Version = truncate(v.Str()) case semconv.AttributeServiceInstanceID: - out.Service = populateNil(out.Service) - out.Service.Node = populateNil(out.Service.Node) + if out.Service == nil { + out.Service = modelpb.ServiceFromVTPool() + } + if out.Service.Node == nil { + out.Service.Node = modelpb.ServiceNodeFromVTPool() + } out.Service.Node.Name = truncate(v.Str()) // deployment.* case semconv.AttributeDeploymentEnvironment: - out.Service = populateNil(out.Service) + if out.Service == nil { + out.Service = modelpb.ServiceFromVTPool() + } out.Service.Environment = truncate(v.Str()) // telemetry.sdk.* case semconv.AttributeTelemetrySDKName: - out.Agent = populateNil(out.Agent) + if out.Agent == nil { + out.Agent = modelpb.AgentFromVTPool() + } out.Agent.Name = truncate(v.Str()) case semconv.AttributeTelemetrySDKVersion: - out.Agent = populateNil(out.Agent) + if out.Agent == nil { + out.Agent = modelpb.AgentFromVTPool() + } out.Agent.Version = truncate(v.Str()) case semconv.AttributeTelemetrySDKLanguage: - out.Service = populateNil(out.Service) - out.Service.Language = populateNil(out.Service.Language) + if out.Service == nil { + out.Service = modelpb.ServiceFromVTPool() + } + if out.Service.Language == nil { + out.Service.Language = modelpb.LanguageFromVTPool() + } out.Service.Language.Name = truncate(v.Str()) // cloud.* case semconv.AttributeCloudProvider: - out.Cloud = populateNil(out.Cloud) + if out.Cloud == nil { + out.Cloud = modelpb.CloudFromVTPool() + } out.Cloud.Provider = truncate(v.Str()) case semconv.AttributeCloudAccountID: - out.Cloud = populateNil(out.Cloud) + if out.Cloud == nil { + out.Cloud = modelpb.CloudFromVTPool() + } out.Cloud.AccountId = truncate(v.Str()) case semconv.AttributeCloudRegion: - out.Cloud = populateNil(out.Cloud) + if out.Cloud == nil { + out.Cloud = modelpb.CloudFromVTPool() + } out.Cloud.Region = truncate(v.Str()) case semconv.AttributeCloudAvailabilityZone: - out.Cloud = populateNil(out.Cloud) + if out.Cloud == nil { + out.Cloud = modelpb.CloudFromVTPool() + } out.Cloud.AvailabilityZone = truncate(v.Str()) case semconv.AttributeCloudPlatform: - out.Cloud = populateNil(out.Cloud) + if out.Cloud == nil { + out.Cloud = modelpb.CloudFromVTPool() + } out.Cloud.ServiceName = truncate(v.Str()) // container.* case semconv.AttributeContainerName: - out.Container = populateNil(out.Container) + if out.Container == nil { + out.Container = modelpb.ContainerFromVTPool() + } out.Container.Name = truncate(v.Str()) case semconv.AttributeContainerID: - out.Container = populateNil(out.Container) + if out.Container == nil { + out.Container = modelpb.ContainerFromVTPool() + } out.Container.Id = truncate(v.Str()) case semconv.AttributeContainerImageName: - out.Container = populateNil(out.Container) + if out.Container == nil { + out.Container = modelpb.ContainerFromVTPool() + } out.Container.ImageName = truncate(v.Str()) case semconv.AttributeContainerImageTag: - out.Container = populateNil(out.Container) + if out.Container == nil { + out.Container = modelpb.ContainerFromVTPool() + } out.Container.ImageTag = truncate(v.Str()) case "container.runtime": - out.Container = populateNil(out.Container) + if out.Container == nil { + out.Container = modelpb.ContainerFromVTPool() + } out.Container.Runtime = truncate(v.Str()) // k8s.* case semconv.AttributeK8SNamespaceName: - out.Kubernetes = populateNil(out.Kubernetes) + if out.Kubernetes == nil { + out.Kubernetes = modelpb.KubernetesFromVTPool() + } out.Kubernetes.Namespace = truncate(v.Str()) case semconv.AttributeK8SNodeName: - out.Kubernetes = populateNil(out.Kubernetes) + if out.Kubernetes == nil { + out.Kubernetes = modelpb.KubernetesFromVTPool() + } out.Kubernetes.NodeName = truncate(v.Str()) case semconv.AttributeK8SPodName: - out.Kubernetes = populateNil(out.Kubernetes) + if out.Kubernetes == nil { + out.Kubernetes = modelpb.KubernetesFromVTPool() + } out.Kubernetes.PodName = truncate(v.Str()) case semconv.AttributeK8SPodUID: - out.Kubernetes = populateNil(out.Kubernetes) + if out.Kubernetes == nil { + out.Kubernetes = modelpb.KubernetesFromVTPool() + } out.Kubernetes.PodUid = truncate(v.Str()) // host.* case semconv.AttributeHostName: - out.Host = populateNil(out.Host) + if out.Host == nil { + out.Host = modelpb.HostFromVTPool() + } out.Host.Hostname = truncate(v.Str()) case semconv.AttributeHostID: - out.Host = populateNil(out.Host) + if out.Host == nil { + out.Host = modelpb.HostFromVTPool() + } out.Host.Id = truncate(v.Str()) case semconv.AttributeHostType: - out.Host = populateNil(out.Host) + if out.Host == nil { + out.Host = modelpb.HostFromVTPool() + } out.Host.Type = truncate(v.Str()) case "host.arch": - out.Host = populateNil(out.Host) + if out.Host == nil { + out.Host = modelpb.HostFromVTPool() + } out.Host.Architecture = truncate(v.Str()) // process.* case semconv.AttributeProcessPID: - out.Process = populateNil(out.Process) + if out.Process == nil { + out.Process = modelpb.ProcessFromVTPool() + } out.Process.Pid = uint32(v.Int()) case semconv.AttributeProcessCommandLine: - out.Process = populateNil(out.Process) + if out.Process == nil { + out.Process = modelpb.ProcessFromVTPool() + } out.Process.CommandLine = truncate(v.Str()) case semconv.AttributeProcessExecutablePath: - out.Process = populateNil(out.Process) + if out.Process == nil { + out.Process = modelpb.ProcessFromVTPool() + } out.Process.Executable = truncate(v.Str()) case "process.runtime.name": - out.Service = populateNil(out.Service) - out.Service.Runtime = populateNil(out.Service.Runtime) + if out.Service == nil { + out.Service = modelpb.ServiceFromVTPool() + } + if out.Service.Runtime == nil { + out.Service.Runtime = modelpb.RuntimeFromVTPool() + } out.Service.Runtime.Name = truncate(v.Str()) case "process.runtime.version": - out.Service = populateNil(out.Service) - out.Service.Runtime = populateNil(out.Service.Runtime) + if out.Service == nil { + out.Service = modelpb.ServiceFromVTPool() + } + if out.Service.Runtime == nil { + out.Service.Runtime = modelpb.RuntimeFromVTPool() + } out.Service.Runtime.Version = truncate(v.Str()) // os.* case semconv.AttributeOSType: - out.Host = populateNil(out.Host) - out.Host.Os = populateNil(out.Host.Os) + if out.Host == nil { + out.Host = modelpb.HostFromVTPool() + } + if out.Host.Os == nil { + out.Host.Os = modelpb.OSFromVTPool() + } out.Host.Os.Platform = strings.ToLower(truncate(v.Str())) case semconv.AttributeOSDescription: - out.Host = populateNil(out.Host) - out.Host.Os = populateNil(out.Host.Os) + if out.Host == nil { + out.Host = modelpb.HostFromVTPool() + } + if out.Host.Os == nil { + out.Host.Os = modelpb.OSFromVTPool() + } out.Host.Os.Full = truncate(v.Str()) case semconv.AttributeOSName: - out.Host = populateNil(out.Host) - out.Host.Os = populateNil(out.Host.Os) + if out.Host == nil { + out.Host = modelpb.HostFromVTPool() + } + if out.Host.Os == nil { + out.Host.Os = modelpb.OSFromVTPool() + } out.Host.Os.Name = truncate(v.Str()) case semconv.AttributeOSVersion: - out.Host = populateNil(out.Host) - out.Host.Os = populateNil(out.Host.Os) + if out.Host == nil { + out.Host = modelpb.HostFromVTPool() + } + if out.Host.Os == nil { + out.Host.Os = modelpb.OSFromVTPool() + } out.Host.Os.Version = truncate(v.Str()) // device.* case semconv.AttributeDeviceID: - out.Device = populateNil(out.Device) + if out.Device == nil { + out.Device = modelpb.DeviceFromVTPool() + } out.Device.Id = truncate(v.Str()) case semconv.AttributeDeviceModelIdentifier: - out.Device = populateNil(out.Device) - out.Device.Model = populateNil(out.Device.Model) + if out.Device == nil { + out.Device = modelpb.DeviceFromVTPool() + } + if out.Device.Model == nil { + out.Device.Model = modelpb.DeviceModelFromVTPool() + } out.Device.Model.Identifier = truncate(v.Str()) case semconv.AttributeDeviceModelName: - out.Device = populateNil(out.Device) - out.Device.Model = populateNil(out.Device.Model) + if out.Device == nil { + out.Device = modelpb.DeviceFromVTPool() + } + if out.Device.Model == nil { + out.Device.Model = modelpb.DeviceModelFromVTPool() + } out.Device.Model.Name = truncate(v.Str()) case "device.manufacturer": - out.Device = populateNil(out.Device) + if out.Device == nil { + out.Device = modelpb.DeviceFromVTPool() + } out.Device.Manufacturer = truncate(v.Str()) // Legacy OpenCensus attributes. @@ -231,11 +327,17 @@ func translateResourceMetadata(resource pcommon.Resource, out *modelpb.APMEvent) const nVersionParts = 3 versionParts := strings.SplitN(exporterVersion, "-", nVersionParts) if out.GetService().GetLanguage().GetName() == "" && len(versionParts) == nVersionParts { - out.Service = populateNil(out.Service) - out.Service.Language = populateNil(out.Service.Language) + if out.Service == nil { + out.Service = modelpb.ServiceFromVTPool() + } + if out.Service.Language == nil { + out.Service.Language = modelpb.LanguageFromVTPool() + } out.Service.Language.Name = versionParts[1] } - out.Agent = populateNil(out.Agent) + if out.Agent == nil { + out.Agent = modelpb.AgentFromVTPool() + } if v := versionParts[len(versionParts)-1]; v != "" { out.Agent.Version = v } @@ -255,12 +357,16 @@ func translateResourceMetadata(resource pcommon.Resource, out *modelpb.APMEvent) } if out.GetService().GetName() == "" { - out.Service = populateNil(out.Service) + if out.Service == nil { + out.Service = modelpb.ServiceFromVTPool() + } // service.name is a required field. out.Service.Name = "unknown" } if out.GetAgent().GetName() == "" { - out.Agent = populateNil(out.Agent) + if out.Agent == nil { + out.Agent = modelpb.AgentFromVTPool() + } // agent.name is a required field. out.Agent.Name = "otlp" } @@ -269,11 +375,17 @@ func translateResourceMetadata(resource pcommon.Resource, out *modelpb.APMEvent) out.Agent.Version = "unknown" } if out.GetService().GetLanguage().GetName() != "" { - out.Agent = populateNil(out.Agent) + if out.Agent == nil { + out.Agent = modelpb.AgentFromVTPool() + } out.Agent.Name = fmt.Sprintf("%s/%s", out.Agent.Name, out.Service.Language.Name) } else { - out.Service = populateNil(out.Service) - out.Service.Language = populateNil(out.Service.Language) + if out.Service == nil { + out.Service = modelpb.ServiceFromVTPool() + } + if out.Service.Language == nil { + out.Service.Language = modelpb.LanguageFromVTPool() + } out.Service.Language.Name = "unknown" } @@ -352,10 +464,3 @@ func setLabel(key string, event *modelpb.APMEvent, v interface{}) { } } } - -func populateNil[T any](a *T) *T { - if a == nil { - return new(T) - } - return a -} diff --git a/input/otlp/metrics.go b/input/otlp/metrics.go index b6658e44..ffc33def 100644 --- a/input/otlp/metrics.go +++ b/input/otlp/metrics.go @@ -72,21 +72,19 @@ func (c *Consumer) convertMetrics(metrics pmetric.Metrics, receiveTimestamp time } func (c *Consumer) convertResourceMetrics(resourceMetrics pmetric.ResourceMetrics, receiveTimestamp time.Time, out *modelpb.Batch) { - baseEvent := modelpb.APMEvent{ - Event: &modelpb.Event{ - Received: modelpb.FromTime(receiveTimestamp), - }, - } + baseEvent := modelpb.APMEventFromVTPool() + baseEvent.Event = modelpb.EventFromVTPool() + baseEvent.Event.Received = modelpb.FromTime(receiveTimestamp) var timeDelta time.Duration resource := resourceMetrics.Resource() - translateResourceMetadata(resource, &baseEvent) + translateResourceMetadata(resource, baseEvent) if exportTimestamp, ok := exportTimestamp(resource); ok { timeDelta = receiveTimestamp.Sub(exportTimestamp) } scopeMetrics := resourceMetrics.ScopeMetrics() for i := 0; i < scopeMetrics.Len(); i++ { - c.convertScopeMetrics(scopeMetrics.At(i), &baseEvent, timeDelta, out) + c.convertScopeMetrics(scopeMetrics.At(i), baseEvent, timeDelta, out) } } @@ -111,7 +109,9 @@ func (c *Consumer) convertScopeMetrics( for _, s := range ms.samples { metrs = append(metrs, s) } - event.Metricset = &modelpb.Metricset{Samples: metrs, Name: "app"} + event.Metricset = modelpb.MetricsetFromVTPool() + event.Metricset.Samples = metrs + event.Metricset.Name = "app" if ms.attributes.Len() > 0 { initEventLabels(event) ms.attributes.Range(func(k string, v pcommon.Value) bool { @@ -206,13 +206,12 @@ func numberSample(dp pmetric.NumberDataPoint, metricType modelpb.MetricType) (mo } func summarySample(dp pmetric.SummaryDataPoint) *modelpb.MetricsetSample { - return &modelpb.MetricsetSample{ - Type: modelpb.MetricType_METRIC_TYPE_SUMMARY, - Summary: &modelpb.SummaryMetric{ - Count: uint64(dp.Count()), - Sum: dp.Sum(), - }, - } + ms := modelpb.MetricsetSampleFromVTPool() + ms.Type = modelpb.MetricType_METRIC_TYPE_SUMMARY + ms.Summary = modelpb.SummaryMetricFromVTPool() + ms.Summary.Count = uint64(dp.Count()) + ms.Summary.Sum = dp.Sum() + return ms } func histogramSample(bucketCounts pcommon.UInt64Slice, explicitBounds pcommon.Float64Slice) (*modelpb.MetricsetSample, bool) { @@ -228,7 +227,7 @@ func histogramSample(bucketCounts pcommon.UInt64Slice, explicitBounds pcommon.Fl // The values in the explicit_bounds array must be strictly increasing. // if bucketCounts.Len() != explicitBounds.Len()+1 || explicitBounds.Len() == 0 { - return &modelpb.MetricsetSample{}, false + return modelpb.MetricsetSampleFromVTPool(), false } // For the bucket values, we follow the approach described by Prometheus's @@ -271,13 +270,12 @@ func histogramSample(bucketCounts pcommon.UInt64Slice, explicitBounds pcommon.Fl counts = append(counts, uint64(count)) values = append(values, value) } - return &modelpb.MetricsetSample{ - Type: modelpb.MetricType_METRIC_TYPE_HISTOGRAM, - Histogram: &modelpb.Histogram{ - Counts: counts, - Values: values, - }, - }, true + ms := modelpb.MetricsetSampleFromVTPool() + ms.Type = modelpb.MetricType_METRIC_TYPE_HISTOGRAM + ms.Histogram = modelpb.HistogramFromVTPool() + ms.Histogram.Counts = counts + ms.Histogram.Values = values + return ms, true } type metricsets map[metricsetKey]metricset diff --git a/input/otlp/traces.go b/input/otlp/traces.go index 0eb413ae..9e43efcc 100644 --- a/input/otlp/traces.go +++ b/input/otlp/traces.go @@ -102,20 +102,18 @@ func (c *Consumer) convertResourceSpans( receiveTimestamp time.Time, out *modelpb.Batch, ) { - baseEvent := modelpb.APMEvent{ - Event: &modelpb.Event{ - Received: modelpb.FromTime(receiveTimestamp), - }, - } + baseEvent := modelpb.APMEventFromVTPool() + baseEvent.Event = modelpb.EventFromVTPool() + baseEvent.Event.Received = modelpb.FromTime(receiveTimestamp) var timeDelta time.Duration resource := resourceSpans.Resource() - translateResourceMetadata(resource, &baseEvent) + translateResourceMetadata(resource, baseEvent) if exportTimestamp, ok := exportTimestamp(resource); ok { timeDelta = receiveTimestamp.Sub(exportTimestamp) } scopeSpans := resourceSpans.ScopeSpans() for i := 0; i < scopeSpans.Len(); i++ { - c.convertScopeSpans(scopeSpans.At(i), &baseEvent, timeDelta, out) + c.convertScopeSpans(scopeSpans.At(i), baseEvent, timeDelta, out) } } @@ -160,36 +158,34 @@ func (c *Consumer) convertSpan( initEventLabels(event) event.Timestamp = modelpb.FromTime(startTime.Add(timeDelta)) if id := hexTraceID(otelSpan.TraceID()); id != "" { - event.Trace = &modelpb.Trace{ - Id: id, - } + event.Trace = modelpb.TraceFromVTPool() + event.Trace.Id = id + } + if event.Event == nil { + event.Event = modelpb.EventFromVTPool() } - event.Event = populateNil(event.Event) event.Event.Duration = uint64(duration) event.Event.Outcome = spanStatusOutcome(otelSpan.Status()) if parentID != "" { event.ParentId = parentID } if root || otelSpan.Kind() == ptrace.SpanKindServer || otelSpan.Kind() == ptrace.SpanKindConsumer { - event.Transaction = &modelpb.Transaction{ - Id: spanID, - Name: name, - Sampled: true, - RepresentativeCount: representativeCount, - } + event.Transaction = modelpb.TransactionFromVTPool() + event.Transaction.Id = spanID + event.Transaction.Name = name + event.Transaction.Sampled = true + event.Transaction.RepresentativeCount = representativeCount if spanID != "" { - event.Span = &modelpb.Span{ - Id: spanID, - } + event.Span = modelpb.SpanFromVTPool() + event.Span.Id = spanID } TranslateTransaction(otelSpan.Attributes(), otelSpan.Status(), otelLibrary, event) } else { - event.Span = &modelpb.Span{ - Id: spanID, - Name: name, - RepresentativeCount: representativeCount, - } + event.Span = modelpb.SpanFromVTPool() + event.Span.Id = spanID + event.Span.Name = name + event.Span.RepresentativeCount = representativeCount TranslateSpan(otelSpan.Kind(), otelSpan.Attributes(), event) } translateSpanLinks(event, otelSpan.Links()) @@ -203,10 +199,11 @@ func (c *Consumer) convertSpan( events := otelSpan.Events() event = event.CloneVT() - event.Labels = baseEvent.Labels // only copy common labels to span events - event.NumericLabels = baseEvent.NumericLabels // only copy common labels to span events - event.Event = &modelpb.Event{Received: baseEvent.Event.Received} // only copy event.received to span events - event.Destination = nil // don't set destination for span events + event.Labels = baseEvent.Labels // only copy common labels to span events + event.NumericLabels = baseEvent.NumericLabels // only copy common labels to span events + event.Event = modelpb.EventFromVTPool() + event.Event.Received = baseEvent.Event.Received // only copy event.received to span events + event.Destination = nil // don't set destination for span events for i := 0; i < events.Len(); i++ { *out = append(*out, c.convertSpanEvent(events.At(i), event, timeDelta)) } @@ -268,7 +265,9 @@ func TranslateTransaction( httpResponse.StatusCode = uint32(v.Int()) http.Response = &httpResponse case semconv.AttributeNetPeerPort: - event.Source = populateNil(event.Source) + if event.Source == nil { + event.Source = modelpb.SourceFromVTPool() + } event.Source.Port = uint32(v.Int()) case semconv.AttributeNetHostPort: netHostPort = int(v.Int()) @@ -318,47 +317,79 @@ func TranslateTransaction( httpServerName = stringval case semconv.AttributeHTTPClientIP: if ip, err := modelpb.ParseIP(stringval); err == nil { - event.Client = populateNil(event.Client) + if event.Client == nil { + event.Client = modelpb.ClientFromVTPool() + } event.Client.Ip = ip } case semconv.AttributeHTTPUserAgent, attributeUserAgentOriginal: - event.UserAgent = populateNil(event.UserAgent) + if event.UserAgent == nil { + event.UserAgent = modelpb.UserAgentFromVTPool() + } event.UserAgent.Original = stringval // net.* case semconv.AttributeNetPeerIP: - event.Source = populateNil(event.Source) + if event.Source == nil { + event.Source = modelpb.SourceFromVTPool() + } if ip, err := modelpb.ParseIP(stringval); err == nil { event.Source.Ip = ip } case semconv.AttributeNetPeerName: - event.Source = populateNil(event.Source) + if event.Source == nil { + event.Source = modelpb.SourceFromVTPool() + } event.Source.Domain = stringval case semconv.AttributeNetHostName: netHostName = stringval case attributeNetworkConnectionType: - event.Network = populateNil(event.Network) - event.Network.Connection = populateNil(event.Network.Connection) + if event.Network == nil { + event.Network = modelpb.NetworkFromVTPool() + } + if event.Network.Connection == nil { + event.Network.Connection = modelpb.NetworkConnectionFromVTPool() + } event.Network.Connection.Type = stringval case attributeNetworkConnectionSubtype: - event.Network = populateNil(event.Network) - event.Network.Connection = populateNil(event.Network.Connection) + if event.Network == nil { + event.Network = modelpb.NetworkFromVTPool() + } + if event.Network.Connection == nil { + event.Network.Connection = modelpb.NetworkConnectionFromVTPool() + } event.Network.Connection.Subtype = stringval case attributeNetworkMCC: - event.Network = populateNil(event.Network) - event.Network.Carrier = populateNil(event.Network.Carrier) + if event.Network == nil { + event.Network = modelpb.NetworkFromVTPool() + } + if event.Network.Carrier == nil { + event.Network.Carrier = modelpb.NetworkCarrierFromVTPool() + } event.Network.Carrier.Mcc = stringval case attributeNetworkMNC: - event.Network = populateNil(event.Network) - event.Network.Carrier = populateNil(event.Network.Carrier) + if event.Network == nil { + event.Network = modelpb.NetworkFromVTPool() + } + if event.Network.Carrier == nil { + event.Network.Carrier = modelpb.NetworkCarrierFromVTPool() + } event.Network.Carrier.Mnc = stringval case attributeNetworkCarrierName: - event.Network = populateNil(event.Network) - event.Network.Carrier = populateNil(event.Network.Carrier) + if event.Network == nil { + event.Network = modelpb.NetworkFromVTPool() + } + if event.Network.Carrier == nil { + event.Network.Carrier = modelpb.NetworkCarrierFromVTPool() + } event.Network.Carrier.Name = stringval case attributeNetworkICC: - event.Network = populateNil(event.Network) - event.Network.Carrier = populateNil(event.Network.Carrier) + if event.Network == nil { + event.Network = modelpb.NetworkFromVTPool() + } + if event.Network.Carrier == nil { + event.Network.Carrier = modelpb.NetworkCarrierFromVTPool() + } event.Network.Carrier.Icc = stringval // messaging.* @@ -387,7 +418,9 @@ func TranslateTransaction( case "type": event.Transaction.Type = stringval case "session.id": - event.Session = populateNil(event.Session) + if event.Session == nil { + event.Session = modelpb.SessionFromVTPool() + } event.Session.Id = stringval case semconv.AttributeServiceVersion: // NOTE support for sending service.version as a span tag @@ -449,11 +482,10 @@ func TranslateTransaction( } if event.Client == nil && event.Source != nil { - event.Client = &modelpb.Client{ - Ip: event.Source.Ip, - Port: event.Source.Port, - Domain: event.Source.Domain, - } + event.Client = modelpb.ClientFromVTPool() + event.Client.Ip = event.Source.Ip + event.Client.Port = event.Source.Port + event.Client.Domain = event.Source.Domain } if samplerType != (pcommon.Value{}) { @@ -465,11 +497,12 @@ func TranslateTransaction( event.Transaction.Result = spanStatusResult(spanStatus) } if name := library.Name(); name != "" { - event.Service = populateNil(event.Service) - event.Service.Framework = &modelpb.Framework{ - Name: name, - Version: library.Version(), + if event.Service == nil { + event.Service = modelpb.ServiceFromVTPool() } + event.Service.Framework = modelpb.FrameworkFromVTPool() + event.Service.Framework.Name = name + event.Service.Framework.Version = library.Version() } } @@ -606,28 +639,52 @@ func TranslateSpan(spanKind ptrace.SpanKind, attributes pcommon.Map, event *mode case "peer.address": peerAddress = stringval case attributeNetworkConnectionType: - event.Network = populateNil(event.Network) - event.Network.Connection = populateNil(event.Network.Connection) + if event.Network == nil { + event.Network = modelpb.NetworkFromVTPool() + } + if event.Network.Connection == nil { + event.Network.Connection = modelpb.NetworkConnectionFromVTPool() + } event.Network.Connection.Type = stringval case attributeNetworkConnectionSubtype: - event.Network = populateNil(event.Network) - event.Network.Connection = populateNil(event.Network.Connection) + if event.Network == nil { + event.Network = modelpb.NetworkFromVTPool() + } + if event.Network.Connection == nil { + event.Network.Connection = modelpb.NetworkConnectionFromVTPool() + } event.Network.Connection.Subtype = stringval case attributeNetworkMCC: - event.Network = populateNil(event.Network) - event.Network.Carrier = populateNil(event.Network.Carrier) + if event.Network == nil { + event.Network = modelpb.NetworkFromVTPool() + } + if event.Network.Carrier == nil { + event.Network.Carrier = modelpb.NetworkCarrierFromVTPool() + } event.Network.Carrier.Mcc = stringval case attributeNetworkMNC: - event.Network = populateNil(event.Network) - event.Network.Carrier = populateNil(event.Network.Carrier) + if event.Network == nil { + event.Network = modelpb.NetworkFromVTPool() + } + if event.Network.Carrier == nil { + event.Network.Carrier = modelpb.NetworkCarrierFromVTPool() + } event.Network.Carrier.Mnc = stringval case attributeNetworkCarrierName: - event.Network = populateNil(event.Network) - event.Network.Carrier = populateNil(event.Network.Carrier) + if event.Network == nil { + event.Network = modelpb.NetworkFromVTPool() + } + if event.Network.Carrier == nil { + event.Network.Carrier = modelpb.NetworkCarrierFromVTPool() + } event.Network.Carrier.Name = stringval case attributeNetworkICC: - event.Network = populateNil(event.Network) - event.Network.Carrier = populateNil(event.Network.Carrier) + if event.Network == nil { + event.Network = modelpb.NetworkFromVTPool() + } + if event.Network.Carrier == nil { + event.Network.Carrier = modelpb.NetworkCarrierFromVTPool() + } event.Network.Carrier.Icc = stringval // server.* @@ -636,7 +693,9 @@ func TranslateSpan(spanKind ptrace.SpanKind, attributes pcommon.Map, event *mode // session.* case "session.id": - event.Session = populateNil(event.Session) + if event.Session == nil { + event.Session = modelpb.SessionFromVTPool() + } event.Session.Id = stringval // messaging.* @@ -746,7 +805,9 @@ func TranslateSpan(spanKind ptrace.SpanKind, attributes pcommon.Map, event *mode if http.SizeVT() != 0 { event.Http = &http } - event.Url = populateNil(event.Url) + if event.Url == nil { + event.Url = modelpb.URLFromVTPool() + } event.Url.Original = httpURL } if isDatabase { @@ -848,7 +909,9 @@ func TranslateSpan(spanKind ptrace.SpanKind, attributes pcommon.Map, event *mode } if destAddr != "" { - event.Destination = &modelpb.Destination{Address: destAddr, Port: uint32(destPort)} + event.Destination = modelpb.DestinationFromVTPool() + event.Destination.Address = destAddr + event.Destination.Port = uint32(destPort) } if destinationService.SizeVT() != 0 { if destinationService.Type == "" { @@ -950,7 +1013,9 @@ func (c *Consumer) convertSpanEvent( setErrorContext(event, parent) } else { // Set "event.kind" to indicate this is a log event. - event.Event = populateNil(event.Event) + if event.Event == nil { + event.Event = modelpb.EventFromVTPool() + } event.Event.Kind = "event" event.Message = spanEvent.Name() setLogContext(event, parent) @@ -1013,15 +1078,15 @@ func (c *Consumer) convertJaegerErrorSpanEvent(event ptrace.SpanEvent, apmEvent ) return nil } - e := &modelpb.Error{} + e := modelpb.ErrorFromVTPool() if logMessage != "" { - e.Log = &modelpb.ErrorLog{Message: logMessage} + e.Log = modelpb.ErrorLogFromVTPool() + e.Log.Message = logMessage } if exMessage != "" || exType != "" { - e.Exception = &modelpb.Exception{ - Message: exMessage, - Type: exType, - } + e.Exception = modelpb.ExceptionFromVTPool() + e.Exception.Message = exMessage + e.Exception.Type = exType } return e } @@ -1031,14 +1096,12 @@ func setErrorContext(out *modelpb.APMEvent, parent *modelpb.APMEvent) { out.Http = parent.Http out.Url = parent.Url if parent.Transaction != nil { - out.Transaction = &modelpb.Transaction{ - Id: parent.Transaction.Id, - Sampled: parent.Transaction.Sampled, - Type: parent.Transaction.Type, - } - out.Span = &modelpb.Span{ - Id: parent.Transaction.Id, - } + out.Transaction = modelpb.TransactionFromVTPool() + out.Transaction.Id = parent.Transaction.Id + out.Transaction.Sampled = parent.Transaction.Sampled + out.Transaction.Type = parent.Transaction.Type + out.Span = modelpb.SpanFromVTPool() + out.Span.Id = parent.Transaction.Id out.Error.Custom = parent.Transaction.Custom out.ParentId = parent.Transaction.Id } @@ -1049,17 +1112,14 @@ func setErrorContext(out *modelpb.APMEvent, parent *modelpb.APMEvent) { func setLogContext(out *modelpb.APMEvent, parent *modelpb.APMEvent) { if parent.Transaction != nil { - out.Transaction = &modelpb.Transaction{ - Id: parent.Transaction.Id, - } - out.Span = &modelpb.Span{ - Id: parent.Transaction.Id, - } + out.Transaction = modelpb.TransactionFromVTPool() + out.Transaction.Id = parent.Transaction.Id + out.Span = modelpb.SpanFromVTPool() + out.Span.Id = parent.Transaction.Id } if parent.Span != nil { - out.Span = &modelpb.Span{ - Id: parent.Span.Id, - } + out.Span = modelpb.SpanFromVTPool() + out.Span.Id = parent.Span.Id } } @@ -1068,14 +1128,16 @@ func translateSpanLinks(out *modelpb.APMEvent, in ptrace.SpanLinkSlice) { if n == 0 { return } - out.Span = populateNil(out.Span) + if out.Span == nil { + out.Span = modelpb.SpanFromVTPool() + } out.Span.Links = make([]*modelpb.SpanLink, n) for i := 0; i < n; i++ { link := in.At(i) - out.Span.Links[i] = &modelpb.SpanLink{ - SpanId: hexSpanID(link.SpanID()), - TraceId: hexTraceID(link.TraceID()), - } + sl := modelpb.SpanLinkFromVTPool() + sl.SpanId = hexSpanID(link.SpanID()) + sl.TraceId = hexTraceID(link.TraceID()) + out.Span.Links[i] = sl } } From 70aa8d9243ddad027f238d983bd7df82bca5be41 Mon Sep 17 00:00:00 2001 From: kruskal <99559985+kruskall@users.noreply.github.com> Date: Thu, 21 Sep 2023 13:17:49 +0200 Subject: [PATCH 3/3] refactor: avoid additional nil checks --- .../internal/modeldecoder/rumv3/decoder.go | 16 ++++------------ .../internal/modeldecoder/v2/decoder.go | 2 +- input/otlp/logs.go | 4 +--- 3 files changed, 6 insertions(+), 16 deletions(-) diff --git a/input/elasticapm/internal/modeldecoder/rumv3/decoder.go b/input/elasticapm/internal/modeldecoder/rumv3/decoder.go index 2fbfe57a..ee9a6be2 100644 --- a/input/elasticapm/internal/modeldecoder/rumv3/decoder.go +++ b/input/elasticapm/internal/modeldecoder/rumv3/decoder.go @@ -192,9 +192,7 @@ func mapToErrorModel(from *errorEvent, event *modelpb.APMEvent) { if event.Http == nil { event.Http = modelpb.HTTPFromVTPool() } - if event.Http.Request == nil { - event.Http.Request = modelpb.HTTPRequestFromVTPool() - } + event.Http.Request = modelpb.HTTPRequestFromVTPool() mapToRequestModel(from.Context.Request, event.Http.Request) if from.Context.Request.HTTPVersion.IsSet() { event.Http.Version = from.Context.Request.HTTPVersion.Val @@ -204,9 +202,7 @@ func mapToErrorModel(from *errorEvent, event *modelpb.APMEvent) { if event.Http == nil { event.Http = modelpb.HTTPFromVTPool() } - if event.Http.Response == nil { - event.Http.Response = modelpb.HTTPResponseFromVTPool() - } + event.Http.Response = modelpb.HTTPResponseFromVTPool() mapToResponseModel(from.Context.Response, event.Http.Response) } if from.Context.Page.IsSet() { @@ -596,9 +592,7 @@ func mapToSpanModel(from *span, event *modelpb.APMEvent) { if event.Http == nil { event.Http = modelpb.HTTPFromVTPool() } - if event.Http.Request == nil { - event.Http.Request = modelpb.HTTPRequestFromVTPool() - } + event.Http.Request = modelpb.HTTPRequestFromVTPool() event.Http.Request.Method = from.Context.HTTP.Method.Val } if from.Context.HTTP.StatusCode.IsSet() { @@ -874,9 +868,7 @@ func mapToTransactionModel(from *transaction, event *modelpb.APMEvent) { out.SpanCount.Started = &started } if from.TraceID.IsSet() { - if event.Trace == nil { - event.Trace = modelpb.TraceFromVTPool() - } + event.Trace = modelpb.TraceFromVTPool() event.Trace.Id = from.TraceID.Val } if from.Type.IsSet() { diff --git a/input/elasticapm/internal/modeldecoder/v2/decoder.go b/input/elasticapm/internal/modeldecoder/v2/decoder.go index 9151254a..8b944c24 100644 --- a/input/elasticapm/internal/modeldecoder/v2/decoder.go +++ b/input/elasticapm/internal/modeldecoder/v2/decoder.go @@ -319,7 +319,7 @@ func mapToDroppedSpansModel(from []transactionDroppedSpanStats, tx *modelpb.Tran to.Outcome = f.Outcome.Val } if f.Duration.IsSet() { - to.Duration = &modelpb.AggregatedDuration{} + to.Duration = modelpb.AggregatedDurationFromVTPool() to.Duration.Count = uint64(f.Duration.Count.Val) sum := f.Duration.Sum if sum.IsSet() { diff --git a/input/otlp/logs.go b/input/otlp/logs.go index ca9709ce..71d43395 100644 --- a/input/otlp/logs.go +++ b/input/otlp/logs.go @@ -116,9 +116,7 @@ func (c *Consumer) convertLogRecord( } } if traceID := record.TraceID(); !traceID.IsEmpty() { - if event.Trace == nil { - event.Trace = modelpb.TraceFromVTPool() - } + event.Trace = modelpb.TraceFromVTPool() event.Trace.Id = hex.EncodeToString(traceID[:]) } if spanID := record.SpanID(); !spanID.IsEmpty() {