diff --git a/internal/pkg/instrumentation/bpf/database/sql/probe.go b/internal/pkg/instrumentation/bpf/database/sql/probe.go index 03a45f9b5..9a4c90da8 100644 --- a/internal/pkg/instrumentation/bpf/database/sql/probe.go +++ b/internal/pkg/instrumentation/bpf/database/sql/probe.go @@ -15,6 +15,7 @@ import ( "go.opentelemetry.io/auto/internal/pkg/instrumentation/context" "go.opentelemetry.io/auto/internal/pkg/instrumentation/probe" + "go.opentelemetry.io/auto/internal/pkg/instrumentation/utils" ) //go:generate go run github.com/cilium/ebpf/cmd/bpf2go -target amd64,arm64 -cc clang -cflags $CFLAGS bpf ./bpf/probe.bpf.c @@ -96,8 +97,8 @@ func convertEvent(e *event) []*probe.SpanEvent { return []*probe.SpanEvent{ { SpanName: "DB", - StartTime: int64(e.StartTime), - EndTime: int64(e.EndTime), + StartTime: utils.BootOffsetToTime(e.StartTime), + EndTime: utils.BootOffsetToTime(e.EndTime), SpanContext: &sc, Attributes: []attribute.KeyValue{ semconv.DBQueryText(query), diff --git a/internal/pkg/instrumentation/bpf/database/sql/probe_test.go b/internal/pkg/instrumentation/bpf/database/sql/probe_test.go index 57a2cdb98..d718de61d 100644 --- a/internal/pkg/instrumentation/bpf/database/sql/probe_test.go +++ b/internal/pkg/instrumentation/bpf/database/sql/probe_test.go @@ -15,19 +15,23 @@ import ( "go.opentelemetry.io/auto/internal/pkg/instrumentation/context" "go.opentelemetry.io/auto/internal/pkg/instrumentation/probe" + "go.opentelemetry.io/auto/internal/pkg/instrumentation/utils" ) func TestProbeConvertEvent(t *testing.T) { - start := time.Now() + start := time.Unix(0, time.Now().UnixNano()) // No wall clock. end := start.Add(1 * time.Second) + startOffset := utils.TimeToBootOffset(start) + endOffset := utils.TimeToBootOffset(end) + traceID := trace.TraceID{1} spanID := trace.SpanID{1} got := convertEvent(&event{ BaseSpanProperties: context.BaseSpanProperties{ - StartTime: uint64(start.UnixNano()), - EndTime: uint64(end.UnixNano()), + StartTime: startOffset, + EndTime: endOffset, SpanContext: context.EBPFSpanContext{TraceID: traceID, SpanID: spanID}, }, // "SELECT * FROM foo" @@ -41,8 +45,8 @@ func TestProbeConvertEvent(t *testing.T) { }) want := &probe.SpanEvent{ SpanName: "DB", - StartTime: int64(start.UnixNano()), - EndTime: int64(end.UnixNano()), + StartTime: start, + EndTime: end, SpanContext: &sc, Attributes: []attribute.KeyValue{ semconv.DBQueryText("SELECT * FROM foo"), diff --git a/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/consumer/probe.go b/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/consumer/probe.go index 980e7509b..2630bb205 100644 --- a/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/consumer/probe.go +++ b/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/consumer/probe.go @@ -15,6 +15,7 @@ import ( "go.opentelemetry.io/auto/internal/pkg/instrumentation/context" "go.opentelemetry.io/auto/internal/pkg/instrumentation/probe" + "go.opentelemetry.io/auto/internal/pkg/instrumentation/utils" "go.opentelemetry.io/auto/internal/pkg/structfield" ) @@ -122,8 +123,8 @@ func convertEvent(e *event) []*probe.SpanEvent { return []*probe.SpanEvent{ { SpanName: kafkaConsumerSpanName(topic), - StartTime: int64(e.StartTime), - EndTime: int64(e.EndTime), + StartTime: utils.BootOffsetToTime(e.StartTime), + EndTime: utils.BootOffsetToTime(e.EndTime), SpanContext: &sc, ParentSpanContext: pscPtr, Attributes: attributes, diff --git a/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/consumer/probe_test.go b/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/consumer/probe_test.go index 30f5d4cfc..fa5d97eb9 100644 --- a/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/consumer/probe_test.go +++ b/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/consumer/probe_test.go @@ -15,19 +15,23 @@ import ( "go.opentelemetry.io/auto/internal/pkg/instrumentation/context" "go.opentelemetry.io/auto/internal/pkg/instrumentation/probe" + "go.opentelemetry.io/auto/internal/pkg/instrumentation/utils" ) func TestProbeConvertEvent(t *testing.T) { - start := time.Now() + start := time.Unix(0, time.Now().UnixNano()) // No wall clock. end := start.Add(1 * time.Second) + startOffset := utils.TimeToBootOffset(start) + endOffset := utils.TimeToBootOffset(end) + traceID := trace.TraceID{1} spanID := trace.SpanID{1} got := convertEvent(&event{ BaseSpanProperties: context.BaseSpanProperties{ - StartTime: uint64(start.UnixNano()), - EndTime: uint64(end.UnixNano()), + StartTime: startOffset, + EndTime: endOffset, SpanContext: context.EBPFSpanContext{TraceID: traceID, SpanID: spanID}, }, // topic1 @@ -47,8 +51,8 @@ func TestProbeConvertEvent(t *testing.T) { }) want := &probe.SpanEvent{ SpanName: kafkaConsumerSpanName("topic1"), - StartTime: int64(start.UnixNano()), - EndTime: int64(end.UnixNano()), + StartTime: start, + EndTime: end, SpanContext: &sc, Attributes: []attribute.KeyValue{ semconv.MessagingSystemKafka, diff --git a/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/producer/probe.go b/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/producer/probe.go index 863eed88a..e0e982f24 100644 --- a/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/producer/probe.go +++ b/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/producer/probe.go @@ -14,6 +14,7 @@ import ( "go.opentelemetry.io/auto/internal/pkg/instrumentation/context" "go.opentelemetry.io/auto/internal/pkg/instrumentation/probe" + "go.opentelemetry.io/auto/internal/pkg/instrumentation/utils" "go.opentelemetry.io/auto/internal/pkg/structfield" ) @@ -138,8 +139,8 @@ func convertEvent(e *event) []*probe.SpanEvent { res = append(res, &probe.SpanEvent{ SpanName: kafkaProducerSpanName(msgTopic), - StartTime: int64(e.StartTime), - EndTime: int64(e.EndTime), + StartTime: utils.BootOffsetToTime(e.StartTime), + EndTime: utils.BootOffsetToTime(e.EndTime), SpanContext: &sc, Attributes: msgAttrs, ParentSpanContext: pscPtr, diff --git a/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/producer/probe_test.go b/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/producer/probe_test.go index 45d1623cc..66486e9b2 100644 --- a/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/producer/probe_test.go +++ b/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/producer/probe_test.go @@ -15,17 +15,21 @@ import ( "go.opentelemetry.io/auto/internal/pkg/instrumentation/context" "go.opentelemetry.io/auto/internal/pkg/instrumentation/probe" + "go.opentelemetry.io/auto/internal/pkg/instrumentation/utils" ) func TestProbeConvertEvent(t *testing.T) { - start := time.Now() + start := time.Unix(0, time.Now().UnixNano()) // No wall clock. end := start.Add(1 * time.Second) + startOffset := utils.TimeToBootOffset(start) + endOffset := utils.TimeToBootOffset(end) + traceID := trace.TraceID{1} got := convertEvent(&event{ - StartTime: uint64(start.UnixNano()), - EndTime: uint64(end.UnixNano()), + StartTime: startOffset, + EndTime: endOffset, Messages: [10]messageAttributes{ { // topic1 @@ -63,8 +67,8 @@ func TestProbeConvertEvent(t *testing.T) { }) want1 := &probe.SpanEvent{ SpanName: kafkaProducerSpanName("topic1"), - StartTime: int64(start.UnixNano()), - EndTime: int64(end.UnixNano()), + StartTime: start, + EndTime: end, SpanContext: &sc1, Attributes: []attribute.KeyValue{ semconv.MessagingKafkaMessageKey("key1"), @@ -78,8 +82,8 @@ func TestProbeConvertEvent(t *testing.T) { want2 := &probe.SpanEvent{ SpanName: kafkaProducerSpanName("topic2"), - StartTime: int64(start.UnixNano()), - EndTime: int64(end.UnixNano()), + StartTime: start, + EndTime: end, SpanContext: &sc2, Attributes: []attribute.KeyValue{ semconv.MessagingKafkaMessageKey("key2"), diff --git a/internal/pkg/instrumentation/bpf/go.opentelemetry.io/otel/traceglobal/probe.go b/internal/pkg/instrumentation/bpf/go.opentelemetry.io/otel/traceglobal/probe.go index 4bbed87bc..ab3862131 100644 --- a/internal/pkg/instrumentation/bpf/go.opentelemetry.io/otel/traceglobal/probe.go +++ b/internal/pkg/instrumentation/bpf/go.opentelemetry.io/otel/traceglobal/probe.go @@ -10,6 +10,7 @@ import ( "go.opentelemetry.io/auto/internal/pkg/inject" "go.opentelemetry.io/auto/internal/pkg/instrumentation/probe" + "go.opentelemetry.io/auto/internal/pkg/instrumentation/utils" "go.opentelemetry.io/auto/internal/pkg/process" "go.opentelemetry.io/auto/internal/pkg/structfield" @@ -207,8 +208,8 @@ func convertEvent(e *event) []*probe.SpanEvent { return []*probe.SpanEvent{ { SpanName: spanName, - StartTime: int64(e.StartTime), - EndTime: int64(e.EndTime), + StartTime: utils.BootOffsetToTime(e.StartTime), + EndTime: utils.BootOffsetToTime(e.EndTime), Attributes: convertAttributes(e.Attributes), SpanContext: &sc, ParentSpanContext: pscPtr, diff --git a/internal/pkg/instrumentation/bpf/go.opentelemetry.io/otel/traceglobal/probe_test.go b/internal/pkg/instrumentation/bpf/go.opentelemetry.io/otel/traceglobal/probe_test.go index a6be025c2..bf9c76778 100644 --- a/internal/pkg/instrumentation/bpf/go.opentelemetry.io/otel/traceglobal/probe_test.go +++ b/internal/pkg/instrumentation/bpf/go.opentelemetry.io/otel/traceglobal/probe_test.go @@ -16,12 +16,16 @@ import ( "go.opentelemetry.io/auto/internal/pkg/instrumentation/context" "go.opentelemetry.io/auto/internal/pkg/instrumentation/probe" + "go.opentelemetry.io/auto/internal/pkg/instrumentation/utils" ) func TestProbeConvertEvent(t *testing.T) { - start := time.Now() + start := time.Unix(0, time.Now().UnixNano()) // No wall clock. end := start.Add(1 * time.Second) + startOffset := utils.TimeToBootOffset(start) + endOffset := utils.TimeToBootOffset(end) + traceID := trace.TraceID{1} spanID := trace.SpanID{1} @@ -30,8 +34,8 @@ func TestProbeConvertEvent(t *testing.T) { got := convertEvent(&event{ BaseSpanProperties: context.BaseSpanProperties{ - StartTime: uint64(start.UnixNano()), - EndTime: uint64(end.UnixNano()), + StartTime: startOffset, + EndTime: endOffset, SpanContext: context.EBPFSpanContext{TraceID: traceID, SpanID: spanID}, }, // span name: "Foo" @@ -104,8 +108,8 @@ func TestProbeConvertEvent(t *testing.T) { }) want := &probe.SpanEvent{ SpanName: "Foo", - StartTime: int64(start.UnixNano()), - EndTime: int64(end.UnixNano()), + StartTime: start, + EndTime: end, SpanContext: &sc, Attributes: []attribute.KeyValue{ attribute.Bool("bool_key", true), diff --git a/internal/pkg/instrumentation/bpf/google.golang.org/grpc/client/probe.go b/internal/pkg/instrumentation/bpf/google.golang.org/grpc/client/probe.go index 366426dbb..066416bab 100644 --- a/internal/pkg/instrumentation/bpf/google.golang.org/grpc/client/probe.go +++ b/internal/pkg/instrumentation/bpf/google.golang.org/grpc/client/probe.go @@ -147,8 +147,8 @@ func convertEvent(e *event) []*probe.SpanEvent { event := &probe.SpanEvent{ SpanName: method, - StartTime: int64(e.StartTime), - EndTime: int64(e.EndTime), + StartTime: utils.BootOffsetToTime(e.StartTime), + EndTime: utils.BootOffsetToTime(e.EndTime), Attributes: attrs, SpanContext: &sc, ParentSpanContext: pscPtr, diff --git a/internal/pkg/instrumentation/bpf/google.golang.org/grpc/server/probe.go b/internal/pkg/instrumentation/bpf/google.golang.org/grpc/server/probe.go index 9264d125d..0397f095b 100644 --- a/internal/pkg/instrumentation/bpf/google.golang.org/grpc/server/probe.go +++ b/internal/pkg/instrumentation/bpf/google.golang.org/grpc/server/probe.go @@ -16,6 +16,7 @@ import ( "go.opentelemetry.io/auto/internal/pkg/inject" "go.opentelemetry.io/auto/internal/pkg/instrumentation/context" "go.opentelemetry.io/auto/internal/pkg/instrumentation/probe" + "go.opentelemetry.io/auto/internal/pkg/instrumentation/utils" "go.opentelemetry.io/auto/internal/pkg/process" "go.opentelemetry.io/auto/internal/pkg/structfield" ) @@ -127,8 +128,8 @@ func convertEvent(e *event) []*probe.SpanEvent { return []*probe.SpanEvent{ { SpanName: method, - StartTime: int64(e.StartTime), - EndTime: int64(e.EndTime), + StartTime: utils.BootOffsetToTime(e.StartTime), + EndTime: utils.BootOffsetToTime(e.EndTime), Attributes: []attribute.KeyValue{ semconv.RPCSystemKey.String("grpc"), semconv.RPCServiceKey.String(method), diff --git a/internal/pkg/instrumentation/bpf/net/http/client/probe.go b/internal/pkg/instrumentation/bpf/net/http/client/probe.go index f7eb679e7..3825f2ac2 100644 --- a/internal/pkg/instrumentation/bpf/net/http/client/probe.go +++ b/internal/pkg/instrumentation/bpf/net/http/client/probe.go @@ -274,8 +274,8 @@ func convertEvent(e *event) []*probe.SpanEvent { spanEvent := &probe.SpanEvent{ SpanName: method, - StartTime: int64(e.StartTime), - EndTime: int64(e.EndTime), + StartTime: utils.BootOffsetToTime(e.StartTime), + EndTime: utils.BootOffsetToTime(e.EndTime), SpanContext: &sc, Attributes: attrs, ParentSpanContext: pscPtr, diff --git a/internal/pkg/instrumentation/bpf/net/http/client/probe_test.go b/internal/pkg/instrumentation/bpf/net/http/client/probe_test.go index 9369b62c6..9fd15627b 100644 --- a/internal/pkg/instrumentation/bpf/net/http/client/probe_test.go +++ b/internal/pkg/instrumentation/bpf/net/http/client/probe_test.go @@ -15,11 +15,16 @@ import ( "go.opentelemetry.io/auto/internal/pkg/instrumentation/context" "go.opentelemetry.io/auto/internal/pkg/instrumentation/probe" + "go.opentelemetry.io/auto/internal/pkg/instrumentation/utils" ) func TestConvertEvent(t *testing.T) { - startTime := time.Now() + startTime := time.Unix(0, time.Now().UnixNano()) // No wall clock. endTime := startTime.Add(1 * time.Second) + + startTimeOffset := utils.TimeToBootOffset(startTime) + endTimeOffset := utils.TimeToBootOffset(endTime) + hostString := "google.com" protoString := "HTTP/1.1" protoFooString := "foo/2.2" @@ -87,8 +92,8 @@ func TestConvertEvent(t *testing.T) { Path: path, Scheme: scheme, BaseSpanProperties: context.BaseSpanProperties{ - StartTime: uint64(startTime.Unix()), - EndTime: uint64(endTime.Unix()), + StartTime: startTimeOffset, + EndTime: endTimeOffset, SpanContext: context.EBPFSpanContext{TraceID: trId, SpanID: spId}, }, }, @@ -96,8 +101,8 @@ func TestConvertEvent(t *testing.T) { { SpanName: methodString, SpanContext: &spanContext, - StartTime: startTime.Unix(), - EndTime: endTime.Unix(), + StartTime: startTime, + EndTime: endTime, Attributes: []attribute.KeyValue{ semconv.HTTPRequestMethodKey.String(methodString), semconv.HTTPResponseStatusCodeKey.Int(200), @@ -120,8 +125,8 @@ func TestConvertEvent(t *testing.T) { Path: path, Scheme: scheme, BaseSpanProperties: context.BaseSpanProperties{ - StartTime: uint64(startTime.Unix()), - EndTime: uint64(endTime.Unix()), + StartTime: startTimeOffset, + EndTime: endTimeOffset, SpanContext: context.EBPFSpanContext{TraceID: trId, SpanID: spId}, }, }, @@ -129,8 +134,8 @@ func TestConvertEvent(t *testing.T) { { SpanName: methodString, SpanContext: &spanContext, - StartTime: startTime.Unix(), - EndTime: endTime.Unix(), + StartTime: startTime, + EndTime: endTime, Attributes: []attribute.KeyValue{ semconv.HTTPRequestMethodKey.String(methodString), semconv.HTTPResponseStatusCodeKey.Int(400), @@ -154,8 +159,8 @@ func TestConvertEvent(t *testing.T) { Path: path, Scheme: scheme, BaseSpanProperties: context.BaseSpanProperties{ - StartTime: uint64(startTime.Unix()), - EndTime: uint64(endTime.Unix()), + StartTime: startTimeOffset, + EndTime: endTimeOffset, SpanContext: context.EBPFSpanContext{TraceID: trId, SpanID: spId}, }, }, @@ -163,8 +168,8 @@ func TestConvertEvent(t *testing.T) { { SpanName: methodString, SpanContext: &spanContext, - StartTime: startTime.Unix(), - EndTime: endTime.Unix(), + StartTime: startTime, + EndTime: endTime, Attributes: []attribute.KeyValue{ semconv.HTTPRequestMethodKey.String(methodString), semconv.HTTPResponseStatusCodeKey.Int(500), @@ -188,8 +193,8 @@ func TestConvertEvent(t *testing.T) { Path: path, Scheme: fooScheme, BaseSpanProperties: context.BaseSpanProperties{ - StartTime: uint64(startTime.Unix()), - EndTime: uint64(endTime.Unix()), + StartTime: startTimeOffset, + EndTime: endTimeOffset, SpanContext: context.EBPFSpanContext{TraceID: trId, SpanID: spId}, }, }, @@ -197,8 +202,8 @@ func TestConvertEvent(t *testing.T) { { SpanName: methodString, SpanContext: &spanContext, - StartTime: startTime.Unix(), - EndTime: endTime.Unix(), + StartTime: startTime, + EndTime: endTime, Attributes: []attribute.KeyValue{ semconv.HTTPRequestMethodKey.String(methodString), semconv.HTTPResponseStatusCodeKey.Int(200), @@ -225,8 +230,8 @@ func TestConvertEvent(t *testing.T) { RawQuery: rawQuery, Fragment: fragment, BaseSpanProperties: context.BaseSpanProperties{ - StartTime: uint64(startTime.Unix()), - EndTime: uint64(endTime.Unix()), + StartTime: startTimeOffset, + EndTime: endTimeOffset, SpanContext: context.EBPFSpanContext{TraceID: trId, SpanID: spId}, }, }, @@ -234,8 +239,8 @@ func TestConvertEvent(t *testing.T) { { SpanName: methodString, SpanContext: &spanContext, - StartTime: startTime.Unix(), - EndTime: endTime.Unix(), + StartTime: startTime, + EndTime: endTime, Attributes: []attribute.KeyValue{ semconv.HTTPRequestMethodKey.String(methodString), semconv.HTTPResponseStatusCodeKey.Int(200), @@ -262,8 +267,8 @@ func TestConvertEvent(t *testing.T) { ForceQuery: 1, OmitHost: 1, BaseSpanProperties: context.BaseSpanProperties{ - StartTime: uint64(startTime.Unix()), - EndTime: uint64(endTime.Unix()), + StartTime: startTimeOffset, + EndTime: endTimeOffset, SpanContext: context.EBPFSpanContext{TraceID: trId, SpanID: spId}, }, }, @@ -271,8 +276,8 @@ func TestConvertEvent(t *testing.T) { { SpanName: methodString, SpanContext: &spanContext, - StartTime: startTime.Unix(), - EndTime: endTime.Unix(), + StartTime: startTime, + EndTime: endTime, Attributes: []attribute.KeyValue{ semconv.HTTPRequestMethodKey.String(methodString), semconv.HTTPResponseStatusCodeKey.Int(200), diff --git a/internal/pkg/instrumentation/bpf/net/http/server/probe.go b/internal/pkg/instrumentation/bpf/net/http/server/probe.go index 3996aa770..d87125921 100644 --- a/internal/pkg/instrumentation/bpf/net/http/server/probe.go +++ b/internal/pkg/instrumentation/bpf/net/http/server/probe.go @@ -18,6 +18,7 @@ import ( "go.opentelemetry.io/auto/internal/pkg/instrumentation/bpf/net/http" "go.opentelemetry.io/auto/internal/pkg/instrumentation/context" "go.opentelemetry.io/auto/internal/pkg/instrumentation/probe" + "go.opentelemetry.io/auto/internal/pkg/instrumentation/utils" "go.opentelemetry.io/auto/internal/pkg/process" "go.opentelemetry.io/auto/internal/pkg/structfield" ) @@ -211,8 +212,8 @@ func convertEvent(e *event) []*probe.SpanEvent { spanEvent := &probe.SpanEvent{ SpanName: spanName, - StartTime: int64(e.StartTime), - EndTime: int64(e.EndTime), + StartTime: utils.BootOffsetToTime(e.StartTime), + EndTime: utils.BootOffsetToTime(e.EndTime), SpanContext: &sc, ParentSpanContext: pscPtr, Attributes: attributes, diff --git a/internal/pkg/instrumentation/bpf/net/http/server/probe_test.go b/internal/pkg/instrumentation/bpf/net/http/server/probe_test.go index bcf50e338..812f50490 100644 --- a/internal/pkg/instrumentation/bpf/net/http/server/probe_test.go +++ b/internal/pkg/instrumentation/bpf/net/http/server/probe_test.go @@ -16,12 +16,16 @@ import ( "go.opentelemetry.io/auto/internal/pkg/instrumentation/context" "go.opentelemetry.io/auto/internal/pkg/instrumentation/probe" + "go.opentelemetry.io/auto/internal/pkg/instrumentation/utils" ) func TestProbeConvertEvent(t *testing.T) { - start := time.Now() + start := time.Unix(0, time.Now().UnixNano()) // No wall clock. end := start.Add(1 * time.Second) + startOffset := utils.TimeToBootOffset(start) + endOffset := utils.TimeToBootOffset(end) + traceID := trace.TraceID{1} spanID := trace.SpanID{1} sc := trace.NewSpanContext(trace.SpanContextConfig{ @@ -39,8 +43,8 @@ func TestProbeConvertEvent(t *testing.T) { name: "basic server test", event: &event{ BaseSpanProperties: context.BaseSpanProperties{ - StartTime: uint64(start.UnixNano()), - EndTime: uint64(end.UnixNano()), + StartTime: startOffset, + EndTime: endOffset, SpanContext: context.EBPFSpanContext{TraceID: traceID, SpanID: spanID}, }, StatusCode: 200, @@ -58,8 +62,8 @@ func TestProbeConvertEvent(t *testing.T) { expected: []*probe.SpanEvent{ { SpanName: "GET", - StartTime: int64(start.UnixNano()), - EndTime: int64(end.UnixNano()), + StartTime: start, + EndTime: end, SpanContext: &sc, Attributes: []attribute.KeyValue{ semconv.HTTPRequestMethodKey.String("GET"), @@ -79,8 +83,8 @@ func TestProbeConvertEvent(t *testing.T) { name: "proto name added when not HTTP", event: &event{ BaseSpanProperties: context.BaseSpanProperties{ - StartTime: uint64(start.UnixNano()), - EndTime: uint64(end.UnixNano()), + StartTime: startOffset, + EndTime: endOffset, SpanContext: context.EBPFSpanContext{TraceID: traceID, SpanID: spanID}, }, StatusCode: 200, @@ -98,8 +102,8 @@ func TestProbeConvertEvent(t *testing.T) { expected: []*probe.SpanEvent{ { SpanName: "GET", - StartTime: int64(start.UnixNano()), - EndTime: int64(end.UnixNano()), + StartTime: start, + EndTime: end, SpanContext: &sc, Attributes: []attribute.KeyValue{ semconv.HTTPRequestMethodKey.String("GET"), @@ -120,8 +124,8 @@ func TestProbeConvertEvent(t *testing.T) { name: "server statuscode 400 doesn't set span.Status", event: &event{ BaseSpanProperties: context.BaseSpanProperties{ - StartTime: uint64(start.UnixNano()), - EndTime: uint64(end.UnixNano()), + StartTime: startOffset, + EndTime: endOffset, SpanContext: context.EBPFSpanContext{TraceID: traceID, SpanID: spanID}, }, StatusCode: 400, @@ -139,8 +143,8 @@ func TestProbeConvertEvent(t *testing.T) { expected: []*probe.SpanEvent{ { SpanName: "GET", - StartTime: int64(start.UnixNano()), - EndTime: int64(end.UnixNano()), + StartTime: start, + EndTime: end, SpanContext: &sc, Attributes: []attribute.KeyValue{ semconv.HTTPRequestMethodKey.String("GET"), @@ -160,8 +164,8 @@ func TestProbeConvertEvent(t *testing.T) { name: "server statuscode 500 sets span.Status", event: &event{ BaseSpanProperties: context.BaseSpanProperties{ - StartTime: uint64(start.UnixNano()), - EndTime: uint64(end.UnixNano()), + StartTime: startOffset, + EndTime: endOffset, SpanContext: context.EBPFSpanContext{TraceID: traceID, SpanID: spanID}, }, StatusCode: 500, @@ -179,8 +183,8 @@ func TestProbeConvertEvent(t *testing.T) { expected: []*probe.SpanEvent{ { SpanName: "GET", - StartTime: int64(start.UnixNano()), - EndTime: int64(end.UnixNano()), + StartTime: start, + EndTime: end, SpanContext: &sc, Attributes: []attribute.KeyValue{ semconv.HTTPRequestMethodKey.String("GET"), diff --git a/internal/pkg/instrumentation/probe/event.go b/internal/pkg/instrumentation/probe/event.go index 6e2e48b69..d6205a5c0 100644 --- a/internal/pkg/instrumentation/probe/event.go +++ b/internal/pkg/instrumentation/probe/event.go @@ -4,6 +4,8 @@ package probe import ( + "time" + "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/trace" @@ -24,8 +26,8 @@ type Status struct { type SpanEvent struct { SpanName string Attributes []attribute.KeyValue - StartTime int64 - EndTime int64 + StartTime time.Time + EndTime time.Time SpanContext *trace.SpanContext ParentSpanContext *trace.SpanContext Status Status diff --git a/internal/pkg/instrumentation/utils/kernel.go b/internal/pkg/instrumentation/utils/kernel.go new file mode 100644 index 000000000..f00d545a9 --- /dev/null +++ b/internal/pkg/instrumentation/utils/kernel.go @@ -0,0 +1,36 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package utils + +import ( + "math" + "time" +) + +var bootTimeOffset = func() int64 { + o, err := estimateBootTimeOffset() + if err != nil { + panic(err) + } + return o +}() + +// BootOffsetToTime returns the timestamp that is nsec number of nanoseconds +// after the estimated boot time of the process. +func BootOffsetToTime(nsec uint64) time.Time { + if nsec > math.MaxInt64 { + nsec = math.MaxInt64 + } + return time.Unix(0, bootTimeOffset+int64(nsec)) +} + +// TimeToBootOffset returns the number of nanoseconds after the estimated boot +// time of the process that the timestamp represent. +func TimeToBootOffset(timestamp time.Time) uint64 { + nsec := timestamp.UnixNano() - bootTimeOffset + if nsec < 0 { + return 0 + } + return uint64(nsec) +} diff --git a/internal/pkg/instrumentation/utils/kernel_linux.go b/internal/pkg/instrumentation/utils/kernel_linux.go index 801706abe..c3a5184a5 100644 --- a/internal/pkg/instrumentation/utils/kernel_linux.go +++ b/internal/pkg/instrumentation/utils/kernel_linux.go @@ -178,7 +178,7 @@ func GetCPUCount() (int, error) { return 0, err } -func EstimateBootTimeOffset() (bootTimeOffset int64, err error) { +func estimateBootTimeOffset() (bootTimeOffset int64, err error) { // The datapath is currently using ktime_get_boot_ns for the pcap timestamp, // which corresponds to CLOCK_BOOTTIME. To be able to convert the the // CLOCK_BOOTTIME to CLOCK_REALTIME (i.e. a unix timestamp). diff --git a/internal/pkg/instrumentation/utils/kernel_other.go b/internal/pkg/instrumentation/utils/kernel_other.go index e3767a734..f9da90dcb 100644 --- a/internal/pkg/instrumentation/utils/kernel_other.go +++ b/internal/pkg/instrumentation/utils/kernel_other.go @@ -30,6 +30,6 @@ func GetCPUCount() (int, error) { return 0, nil } -func EstimateBootTimeOffset() (bootTimeOffset int64, err error) { +func estimateBootTimeOffset() (bootTimeOffset int64, err error) { return 0, nil } diff --git a/internal/pkg/instrumentation/utils/kernel_test.go b/internal/pkg/instrumentation/utils/kernel_test.go new file mode 100644 index 000000000..73ec02c63 --- /dev/null +++ b/internal/pkg/instrumentation/utils/kernel_test.go @@ -0,0 +1,24 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package utils + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +func TestBootOffsetConversion(t *testing.T) { + var sec, nsec int64 = 1e3, 9328646329 + bootTimeOffset + + timestamp := time.Unix(sec, nsec) + t.Logf("timestamp: %v", timestamp) + + offset := uint64((sec * 1e9) + nsec - bootTimeOffset) + t.Logf("offset: %d", offset) + + assert.Equal(t, offset, TimeToBootOffset(timestamp), "TimeToBootOffset") + assert.Equal(t, timestamp, BootOffsetToTime(offset), "BootOffsetToTime") +} diff --git a/internal/pkg/opentelemetry/controller.go b/internal/pkg/opentelemetry/controller.go index eba78c6e4..f7232cc92 100644 --- a/internal/pkg/opentelemetry/controller.go +++ b/internal/pkg/opentelemetry/controller.go @@ -5,13 +5,11 @@ package opentelemetry import ( "context" - "time" "github.com/go-logr/logr" "go.opentelemetry.io/otel/trace" "go.opentelemetry.io/auto/internal/pkg/instrumentation/probe" - "go.opentelemetry.io/auto/internal/pkg/instrumentation/utils" ) // Controller handles OpenTelemetry telemetry generation for events. @@ -20,7 +18,6 @@ type Controller struct { version string tracerProvider trace.TracerProvider tracersMap map[tracerID]trace.Tracer - bootTime int64 } type tracerID struct{ name, version, schema string } @@ -75,31 +72,21 @@ func (c *Controller) Trace(event *probe.Event) { Start(ctx, se.SpanName, trace.WithAttributes(se.Attributes...), trace.WithSpanKind(event.Kind), - trace.WithTimestamp(c.convertTime(se.StartTime))) + trace.WithTimestamp(se.StartTime)) span.SetStatus(se.Status.Code, se.Status.Description) - span.End(trace.WithTimestamp(c.convertTime(se.EndTime))) + span.End(trace.WithTimestamp(se.EndTime)) } } -func (c *Controller) convertTime(t int64) time.Time { - return time.Unix(0, c.bootTime+t) -} - // NewController returns a new initialized [Controller]. func NewController(logger logr.Logger, tracerProvider trace.TracerProvider, ver string) (*Controller, error) { logger = logger.WithName("Controller") - bt, err := utils.EstimateBootTimeOffset() - if err != nil { - return nil, err - } - return &Controller{ logger: logger, version: ver, tracerProvider: tracerProvider, tracersMap: make(map[tracerID]trace.Tracer), - bootTime: bt, }, nil } diff --git a/internal/pkg/opentelemetry/controller_test.go b/internal/pkg/opentelemetry/controller_test.go index 3c67c22bb..3c71551ef 100644 --- a/internal/pkg/opentelemetry/controller_test.go +++ b/internal/pkg/opentelemetry/controller_test.go @@ -78,9 +78,6 @@ func TestTrace(t *testing.T) { ctrl, err := NewController(logger, tp, "test") assert.NoError(t, err) - convertedStartTime := ctrl.convertTime(startTime.Unix()) - convertedEndTime := ctrl.convertTime(endTime.Unix()) - spId, err := trace.SpanIDFromHex("00f067aa0ba902b7") assert.NoError(t, err) trId, err := trace.TraceIDFromHex("00f067aa0ba902b700f067aa0ba902b7") @@ -106,8 +103,8 @@ func TestTrace(t *testing.T) { SpanEvents: []*probe.SpanEvent{ { SpanName: "testSpan", - StartTime: startTime.Unix(), - EndTime: endTime.Unix(), + StartTime: startTime, + EndTime: endTime, SpanContext: &spanContext, TracerSchema: semconv.SchemaURL, }, @@ -117,8 +114,8 @@ func TestTrace(t *testing.T) { { Name: "testSpan", SpanKind: trace.SpanKindClient, - StartTime: convertedStartTime, - EndTime: convertedEndTime, + StartTime: startTime, + EndTime: endTime, Resource: instResource(), InstrumentationLibrary: instrumentation.Scope{ Name: "go.opentelemetry.io/auto/foo/bar", @@ -141,8 +138,8 @@ func TestTrace(t *testing.T) { SpanEvents: []*probe.SpanEvent{ { SpanName: "GET", - StartTime: startTime.Unix(), - EndTime: endTime.Unix(), + StartTime: startTime, + EndTime: endTime, SpanContext: &spanContext, Attributes: []attribute.KeyValue{ semconv.HTTPRequestMethodKey.String("GET"), @@ -158,8 +155,8 @@ func TestTrace(t *testing.T) { { Name: "GET", SpanKind: trace.SpanKindClient, - StartTime: convertedStartTime, - EndTime: convertedEndTime, + StartTime: startTime, + EndTime: endTime, Resource: instResource(), InstrumentationLibrary: instrumentation.Scope{ Name: "go.opentelemetry.io/auto/net/http", @@ -187,8 +184,8 @@ func TestTrace(t *testing.T) { SpanEvents: []*probe.SpanEvent{ { SpanName: "GET", - StartTime: startTime.Unix(), - EndTime: endTime.Unix(), + StartTime: startTime, + EndTime: endTime, SpanContext: &spanContext, Attributes: []attribute.KeyValue{ semconv.HTTPRequestMethodKey.String("GET"), @@ -205,8 +202,8 @@ func TestTrace(t *testing.T) { { Name: "GET", SpanKind: trace.SpanKindClient, - StartTime: convertedStartTime, - EndTime: convertedEndTime, + StartTime: startTime, + EndTime: endTime, Resource: instResource(), InstrumentationLibrary: instrumentation.Scope{ Name: "go.opentelemetry.io/auto/net/http", @@ -234,8 +231,8 @@ func TestTrace(t *testing.T) { SpanEvents: []*probe.SpanEvent{ { SpanName: "very important span", - StartTime: startTime.Unix(), - EndTime: endTime.Unix(), + StartTime: startTime, + EndTime: endTime, SpanContext: &spanContext, Attributes: []attribute.KeyValue{ attribute.Int64("int.value", 42), @@ -254,8 +251,8 @@ func TestTrace(t *testing.T) { { Name: "very important span", SpanKind: trace.SpanKindClient, - StartTime: convertedStartTime, - EndTime: convertedEndTime, + StartTime: startTime, + EndTime: endTime, Resource: instResource(), InstrumentationLibrary: instrumentation.Scope{ Name: "user-tracer",