Skip to content

Commit

Permalink
Introduce model.Trace (#5983)
Browse files Browse the repository at this point in the history
Introduce type model.Trace and field APMEvent.Trace,
replacing {Error,Span,Transaction}.TraceID.
  • Loading branch information
axw authored Aug 24, 2021
1 parent 008e8f0 commit 6754818
Show file tree
Hide file tree
Showing 24 changed files with 165 additions and 119 deletions.
2 changes: 2 additions & 0 deletions model/apmevent.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ type APMEvent struct {
Network Network
Session Session
URL URL
Trace Trace

// Timestamp holds the event timestamp.
//
Expand Down Expand Up @@ -132,6 +133,7 @@ func (e *APMEvent) BeatEvent(ctx context.Context) beat.Event {
fields.maybeSetMapStr("event", e.Event.fields())
fields.maybeSetMapStr("url", e.URL.fields())
fields.maybeSetMapStr("session", e.Session.fields())
fields.maybeSetMapStr("trace", e.Trace.fields())
fields.maybeSetString("message", e.Message)
return event
}
5 changes: 5 additions & 0 deletions model/apmevent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ func TestAPMEventFields(t *testing.T) {
outcome := "success"
destinationAddress := "1.2.3.4"
destinationPort := 1234
traceID := "trace_id"

for _, test := range []struct {
input APMEvent
Expand Down Expand Up @@ -73,6 +74,7 @@ func TestAPMEventFields(t *testing.T) {
Message: "bottle",
Transaction: &Transaction{},
Timestamp: time.Date(2019, 1, 3, 15, 17, 4, 908.596*1e6, time.FixedZone("+0100", 3600)),
Trace: Trace{ID: traceID},
},
output: common.MapStr{
// common fields
Expand Down Expand Up @@ -102,6 +104,9 @@ func TestAPMEventFields(t *testing.T) {
"c": 123,
},
"message": "bottle",
"trace": common.MapStr{
"id": traceID,
},

// fields related to APMEvent.Transaction
"processor": common.MapStr{
Expand Down
5 changes: 1 addition & 4 deletions model/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ const (
type Error struct {
ID string
TransactionID string
TraceID string
ParentID string

GroupingKey string
Expand Down Expand Up @@ -102,11 +101,9 @@ func (e *Error) fields() common.MapStr {
transaction.maybeSetBool("sampled", e.TransactionSampled)
fields.maybeSetMapStr("transaction", common.MapStr(transaction))

var parent, trace mapStr
var parent mapStr
parent.maybeSetString("id", e.ParentID)
trace.maybeSetString("id", e.TraceID)
fields.maybeSetMapStr("parent", common.MapStr(parent))
fields.maybeSetMapStr("trace", common.MapStr(trace))

var errorFields mapStr
errorFields.maybeSetString("id", e.ID)
Expand Down
6 changes: 3 additions & 3 deletions model/modeldecoder/rumv3/decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ func DecodeNestedTransaction(d decoder.Decoder, input *modeldecoder.Input, batch
span := input.Base
mapToSpanModel(&s, &span)
span.Span.TransactionID = transaction.Transaction.ID
span.Span.TraceID = transaction.Transaction.TraceID
span.Trace = transaction.Trace
*batch = append(*batch, span)
}
spans := (*batch)[offset:]
Expand Down Expand Up @@ -277,7 +277,7 @@ func mapToErrorModel(from *errorEvent, event *model.APMEvent) {
event.Timestamp = from.Timestamp.Val
}
if from.TraceID.IsSet() {
out.TraceID = from.TraceID.Val
event.Trace.ID = from.TraceID.Val
}
if from.Transaction.Sampled.IsSet() {
val := from.Transaction.Sampled.Val
Expand Down Expand Up @@ -800,7 +800,7 @@ func mapToTransactionModel(from *transaction, event *model.APMEvent) {
out.SpanCount.Started = &started
}
if from.TraceID.IsSet() {
out.TraceID = from.TraceID.Val
event.Trace.ID = from.TraceID.Val
}
if from.Type.IsSet() {
out.Type = from.Type.Val
Expand Down
1 change: 1 addition & 0 deletions model/modeldecoder/rumv3/metadata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ func metadataExceptions(keys ...string) func(key string) bool {
"Host",
"Event",
"Session",
"Trace",
"URL",

// event-specific fields
Expand Down
2 changes: 1 addition & 1 deletion model/modeldecoder/rumv3/transaction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func TestDecodeNestedTransaction(t *testing.T) {
start := time.Duration(20 * 1000 * 1000)
assert.Equal(t, now.Add(start), batch[3].Timestamp) //add start to timestamp
assert.Equal(t, "100", batch[3].Span.TransactionID)
assert.Equal(t, "1", batch[3].Span.TraceID)
assert.Equal(t, "1", batch[3].Trace.ID)
assert.Equal(t, "100", batch[3].Span.ParentID)

for _, event := range batch {
Expand Down
6 changes: 3 additions & 3 deletions model/modeldecoder/v2/decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ func mapToErrorModel(from *errorEvent, config modeldecoder.Config, event *model.
event.Timestamp = from.Timestamp.Val
}
if from.TraceID.IsSet() {
out.TraceID = from.TraceID.Val
event.Trace.ID = from.TraceID.Val
}
if from.Transaction.Sampled.IsSet() {
val := from.Transaction.Sampled.Val
Expand Down Expand Up @@ -930,7 +930,7 @@ func mapToSpanModel(from *span, config modeldecoder.Config, event *model.APMEven
)
}
if from.TraceID.IsSet() {
out.TraceID = from.TraceID.Val
event.Trace.ID = from.TraceID.Val
}
if from.TransactionID.IsSet() {
out.TransactionID = from.TransactionID.Val
Expand Down Expand Up @@ -1126,7 +1126,7 @@ func mapToTransactionModel(from *transaction, config modeldecoder.Config, event
event.Timestamp = from.Timestamp.Val
}
if from.TraceID.IsSet() {
out.TraceID = from.TraceID.Val
event.Trace.ID = from.TraceID.Val
}
if from.Type.IsSet() {
out.Type = from.Type.Val
Expand Down
2 changes: 2 additions & 0 deletions model/modeldecoder/v2/metadata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ func isUnmappedMetadataField(key string) bool {
"Session.ID",
"Session",
"Session.Sequence",
"Trace",
"Trace.ID",
"URL",
"URL.Original",
"URL.Scheme",
Expand Down
6 changes: 1 addition & 5 deletions model/span.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ type Span struct {
TransactionID string
ParentID string
ChildIDs []string
TraceID string

Message *Message
Name string
Expand Down Expand Up @@ -141,10 +140,7 @@ func (e *Span) fields(apmEvent *APMEvent) common.MapStr {

fields := mapStr{"processor": spanProcessorEntry}

var trace, transaction, parent mapStr
if trace.maybeSetString("id", e.TraceID) {
fields.set("trace", common.MapStr(trace))
}
var transaction, parent mapStr
if transaction.maybeSetString("id", e.TransactionID) {
fields.set("transaction", common.MapStr(transaction))
}
Expand Down
4 changes: 1 addition & 3 deletions model/span_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import (
func TestSpanTransform(t *testing.T) {
path := "test/path"
start := 0.65
hexID, parentID, traceID := "0147258369012345", "abcdef0123456789", "01234567890123456789abcdefa"
hexID, parentID := "0147258369012345", "abcdef0123456789"
subtype := "amqp"
action := "publish"
timestamp := time.Date(2019, 1, 3, 15, 17, 4, 908.596*1e6,
Expand Down Expand Up @@ -65,7 +65,6 @@ func TestSpanTransform(t *testing.T) {
Msg: "Full Span",
Span: Span{
ID: hexID,
TraceID: traceID,
ParentID: parentID,
Name: "myspan",
Type: "myspantype",
Expand Down Expand Up @@ -135,7 +134,6 @@ func TestSpanTransform(t *testing.T) {
},
"processor": common.MapStr{"event": "span", "name": "transaction"},
"timestamp": common.MapStr{"us": timestampUs},
"trace": common.MapStr{"id": traceID},
"parent": common.MapStr{"id": parentID},
"http": common.MapStr{
"response": common.MapStr{"status_code": statusCode},
Expand Down
34 changes: 34 additions & 0 deletions model/trace.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Licensed to Elasticsearch B.V. under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Elasticsearch B.V. licenses this file to you under
// the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

package model

import (
"github.com/elastic/beats/v7/libbeat/common"
)

// Trace holds information about a distributed trace.
type Trace struct {
// ID holds a unique identifier of the trace.
ID string
}

func (t *Trace) fields() common.MapStr {
var fields mapStr
fields.maybeSetString("id", t.ID)
return common.MapStr(fields)
}
5 changes: 1 addition & 4 deletions model/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ var (
type Transaction struct {
ID string
ParentID string
TraceID string

Type string
Name string
Expand Down Expand Up @@ -74,11 +73,9 @@ func (e *Transaction) fields() common.MapStr {
"processor": transactionProcessorEntry,
}

var parent, trace mapStr
var parent mapStr
parent.maybeSetString("id", e.ParentID)
trace.maybeSetString("id", e.TraceID)
fields.maybeSetMapStr("parent", common.MapStr(parent))
fields.maybeSetMapStr("trace", common.MapStr(trace))
if e.HTTP != nil {
fields.maybeSetMapStr("http", e.HTTP.transactionTopLevelFields())
}
Expand Down
6 changes: 3 additions & 3 deletions processor/otel/exceptions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ Caused by: LowLevelException
Service: service,
Agent: agent,
Timestamp: timestamp,
Trace: transactionEvent.Trace,
Error: &model.Error{
TraceID: transactionEvent.Transaction.TraceID,
ParentID: transactionEvent.Transaction.ID,
TransactionID: transactionEvent.Transaction.ID,
TransactionType: transactionEvent.Transaction.Type,
Expand Down Expand Up @@ -161,8 +161,8 @@ Caused by: LowLevelException
Service: service,
Agent: agent,
Timestamp: timestamp,
Trace: transactionEvent.Trace,
Error: &model.Error{
TraceID: transactionEvent.Transaction.TraceID,
ParentID: transactionEvent.Transaction.ID,
TransactionID: transactionEvent.Transaction.ID,
TransactionType: transactionEvent.Transaction.Type,
Expand Down Expand Up @@ -317,8 +317,8 @@ func TestEncodeSpanEventsNonJavaExceptions(t *testing.T) {
Service: service,
Agent: agent,
Timestamp: timestamp,
Trace: transactionEvent.Trace,
Error: &model.Error{
TraceID: transactionEvent.Transaction.TraceID,
ParentID: transactionEvent.Transaction.ID,
TransactionID: transactionEvent.Transaction.ID,
TransactionType: transactionEvent.Transaction.Type,
Expand Down
1 change: 1 addition & 0 deletions processor/otel/metadata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ func transformResourceMetadata(t *testing.T, resourceAttrs map[string]pdata.Attr
otelSpan.SetSpanID(pdata.NewSpanID([8]byte{2}))
events := transformTraces(t, traces)
events[0].Transaction = nil
events[0].Trace = model.Trace{}
events[0].Event.Outcome = ""
events[0].Timestamp = time.Time{}
return events[0]
Expand Down
9 changes: 2 additions & 7 deletions processor/otel/traces.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,6 @@ func (c *Consumer) convertSpan(
parentID = otelSpan.ParentSpanID().HexString()
}

traceID := otelSpan.TraceID().HexString()
spanID := otelSpan.SpanID().HexString()

startTime := otelSpan.StartTimestamp().AsTime()
endTime := otelSpan.EndTimestamp().AsTime()
var durationMillis float64
Expand All @@ -206,15 +203,16 @@ func (c *Consumer) convertSpan(
// now, we assume that the majority of consumption is passive, and
// therefore start a transaction whenever span kind == consumer.
name := otelSpan.Name()
spanID := otelSpan.SpanID().HexString()
event := baseEvent
event.Labels = initEventLabels(event.Labels)
event.Timestamp = startTime.Add(timeDelta)
event.Trace.ID = otelSpan.TraceID().HexString()
event.Event.Outcome = spanStatusOutcome(otelSpan.Status())
if root || otelSpan.Kind() == pdata.SpanKindServer || otelSpan.Kind() == pdata.SpanKindConsumer {
event.Transaction = &model.Transaction{
ID: spanID,
ParentID: parentID,
TraceID: traceID,
Duration: durationMillis,
Name: name,
Sampled: true,
Expand All @@ -224,7 +222,6 @@ func (c *Consumer) convertSpan(
event.Span = &model.Span{
ID: spanID,
ParentID: parentID,
TraceID: traceID,
Duration: durationMillis,
Name: name,
}
Expand Down Expand Up @@ -948,7 +945,6 @@ func convertJaegerErrorSpanEvent(logger *logp.Logger, event pdata.SpanEvent) *mo

func addTransactionCtxToErr(transaction *model.Transaction, err *model.Error) {
err.TransactionID = transaction.ID
err.TraceID = transaction.TraceID
err.ParentID = transaction.ID
err.HTTP = transaction.HTTP
err.Custom = transaction.Custom
Expand All @@ -957,7 +953,6 @@ func addTransactionCtxToErr(transaction *model.Transaction, err *model.Error) {
}

func addSpanCtxToErr(span *model.Span, err *model.Error) {
err.TraceID = span.TraceID
err.ParentID = span.ID
}

Expand Down
4 changes: 2 additions & 2 deletions processor/otel/traces_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -790,8 +790,8 @@ func TestConsumer_JaegerTraceID(t *testing.T) {
require.NoError(t, (&otel.Consumer{Processor: recorder}).ConsumeTraces(context.Background(), traces))

batch := *batches[0]
assert.Equal(t, "00000000000000000000000046467830", batch[0].Transaction.TraceID)
assert.Equal(t, "00000000464678300000000046467830", batch[1].Transaction.TraceID)
assert.Equal(t, "00000000000000000000000046467830", batch[0].Trace.ID)
assert.Equal(t, "00000000464678300000000046467830", batch[1].Trace.ID)
}

func TestConsumer_JaegerTransaction(t *testing.T) {
Expand Down
6 changes: 2 additions & 4 deletions x-pack/apm-server/sampling/eventstorage/sharded_bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func BenchmarkShardedWriteTransactionUncontended(b *testing.B) {
b.RunParallel(func(pb *testing.PB) {
traceID := uuid.Must(uuid.NewV4()).String()
transaction := &model.APMEvent{
Transaction: &model.Transaction{TraceID: traceID, ID: traceID},
Transaction: &model.Transaction{ID: traceID},
}
for pb.Next() {
if err := sharded.WriteTraceEvent(traceID, traceID, transaction); err != nil {
Expand All @@ -48,9 +48,7 @@ func BenchmarkShardedWriteTransactionContended(b *testing.B) {
b.RunParallel(func(pb *testing.PB) {
transactionID := uuid.Must(uuid.NewV4()).String()
transaction := &model.APMEvent{
Transaction: &model.Transaction{
TraceID: traceID, ID: transactionID,
},
Transaction: &model.Transaction{ID: transactionID},
}
for pb.Next() {
if err := sharded.WriteTraceEvent(traceID, transactionID, transaction); err != nil {
Expand Down
5 changes: 2 additions & 3 deletions x-pack/apm-server/sampling/eventstorage/storage_bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func BenchmarkWriteTransaction(b *testing.B) {
traceID := hex.EncodeToString([]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16})
transactionID := hex.EncodeToString([]byte{1, 2, 3, 4, 5, 6, 7, 8})
transaction := &model.APMEvent{
Transaction: &model.Transaction{TraceID: traceID, ID: transactionID},
Transaction: &model.Transaction{ID: transactionID},
}

b.ResetTimer()
Expand Down Expand Up @@ -69,8 +69,7 @@ func BenchmarkReadEvents(b *testing.B) {
transactionID := uuid.Must(uuid.NewV4()).String()
transaction := &model.APMEvent{
Transaction: &model.Transaction{
TraceID: traceID,
ID: transactionID,
ID: transactionID,
},
}
if err := readWriter.WriteTraceEvent(traceID, transactionID, transaction); err != nil {
Expand Down
Loading

0 comments on commit 6754818

Please sign in to comment.