Skip to content
This repository was archived by the owner on Sep 15, 2025. It is now read-only.

Commit 686909f

Browse files
committed
[pkg/otlp/logs] Refactor to use attributes.Translator
1 parent a27805f commit 686909f

File tree

4 files changed

+96
-32
lines changed

4 files changed

+96
-32
lines changed

pkg/otlp/logs/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ require (
99
go.opentelemetry.io/collector/component v0.91.0
1010
go.opentelemetry.io/collector/pdata v1.0.0
1111
go.opentelemetry.io/collector/semconv v0.91.0
12+
go.opentelemetry.io/otel v1.21.0
1213
go.uber.org/zap v1.26.0
1314
)
1415

@@ -31,7 +32,6 @@ require (
3132
go.opentelemetry.io/collector/config/configtelemetry v0.91.0 // indirect
3233
go.opentelemetry.io/collector/confmap v0.91.0 // indirect
3334
go.opentelemetry.io/collector/featuregate v1.0.0 // indirect
34-
go.opentelemetry.io/otel v1.21.0 // indirect
3535
go.opentelemetry.io/otel/metric v1.21.0 // indirect
3636
go.opentelemetry.io/otel/trace v1.21.0 // indirect
3737
go.uber.org/multierr v1.11.0 // indirect

pkg/otlp/logs/transform.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ const (
6464
// Deprecated: use Translator instead.
6565
func Transform(lr plog.LogRecord, res pcommon.Resource, logger *zap.Logger) datadogV2.HTTPLogItem {
6666
host, service := extractHostNameAndServiceName(res.Attributes(), lr.Attributes())
67+
return transform(lr, host, service, res, logger)
68+
}
69+
70+
func transform(lr plog.LogRecord, host, service string, res pcommon.Resource, logger *zap.Logger) datadogV2.HTTPLogItem {
6771
l := datadogV2.HTTPLogItem{
6872
AdditionalProperties: make(map[string]string),
6973
}
@@ -198,8 +202,8 @@ func extractHostNameAndServiceName(resourceAttrs pcommon.Map, logAttrs pcommon.M
198202
if src, ok := attributes.SourceFromAttrs(resourceAttrs); ok && src.Kind == source.HostnameKind {
199203
host = src.Identifier
200204
}
201-
// hostName is blank from resource
202-
// we need to derive from log attributes
205+
// HACK: Check for host in log record attributes if not present in resource attributes.
206+
// This is not aligned with the specification and will be removed in the future.
203207
if host == "" {
204208
if src, ok := attributes.SourceFromAttrs(logAttrs); ok && src.Kind == source.HostnameKind {
205209
host = src.Identifier
@@ -208,8 +212,8 @@ func extractHostNameAndServiceName(resourceAttrs pcommon.Map, logAttrs pcommon.M
208212
if s, ok := resourceAttrs.Get(conventions.AttributeServiceName); ok {
209213
service = s.AsString()
210214
}
211-
// serviceName is blank from resource
212-
// we need to derive from log attributes
215+
// HACK: Check for service in log record attributes if not present in resource attributes.
216+
// This is not aligned with the specification and will be removed in the future.
213217
if service == "" {
214218
if s, ok := logAttrs.Get(conventions.AttributeServiceName); ok {
215219
service = s.AsString()

pkg/otlp/logs/transform_test.go

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,23 @@
1515
package logs
1616

1717
import (
18+
"context"
1819
"fmt"
1920
"testing"
2021

2122
"github.com/DataDog/datadog-api-client-go/v2/api/datadog"
2223
"github.com/DataDog/datadog-api-client-go/v2/api/datadogV2"
24+
"github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/attributes"
2325
"github.com/stretchr/testify/assert"
26+
"github.com/stretchr/testify/require"
27+
"go.opentelemetry.io/collector/component/componenttest"
2428
"go.opentelemetry.io/collector/pdata/pcommon"
2529
"go.opentelemetry.io/collector/pdata/plog"
2630
conventions "go.opentelemetry.io/collector/semconv/v1.6.1"
2731
"go.uber.org/zap/zaptest"
2832
)
2933

30-
func TestTransform(t *testing.T) {
31-
testLogger := zaptest.NewLogger(t)
34+
func TestTranslator(t *testing.T) {
3235
traceID := [16]byte{0x08, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x0, 0x0, 0x0, 0x0, 0x0a}
3336
var spanID [8]byte
3437
copy(spanID[:], traceID[8:])
@@ -57,7 +60,7 @@ func TestTransform(t *testing.T) {
5760
res: pcommon.NewResource(),
5861
},
5962
want: datadogV2.HTTPLogItem{
60-
Ddtags: datadog.PtrString(""),
63+
Ddtags: datadog.PtrString("otel_source:test"),
6164
Message: *datadog.PtrString(""),
6265
AdditionalProperties: map[string]string{
6366
"app": "test",
@@ -83,7 +86,7 @@ func TestTransform(t *testing.T) {
8386
}(),
8487
},
8588
want: datadogV2.HTTPLogItem{
86-
Ddtags: datadog.PtrString("service:otlp_col"),
89+
Ddtags: datadog.PtrString("service:otlp_col,otel_source:test"),
8790
Message: *datadog.PtrString(""),
8891
Service: datadog.PtrString("otlp_col"),
8992
AdditionalProperties: map[string]string{
@@ -112,7 +115,7 @@ func TestTransform(t *testing.T) {
112115
}(),
113116
},
114117
want: datadogV2.HTTPLogItem{
115-
Ddtags: datadog.PtrString("service:otlp_col,foo:bar"),
118+
Ddtags: datadog.PtrString("service:otlp_col,foo:bar,otel_source:test"),
116119
Message: *datadog.PtrString(""),
117120
Service: datadog.PtrString("otlp_col"),
118121
AdditionalProperties: map[string]string{
@@ -140,7 +143,7 @@ func TestTransform(t *testing.T) {
140143
}(),
141144
},
142145
want: datadogV2.HTTPLogItem{
143-
Ddtags: datadog.PtrString(""),
146+
Ddtags: datadog.PtrString("otel_source:test"),
144147
Message: *datadog.PtrString(""),
145148
Service: datadog.PtrString("otlp_col"),
146149
AdditionalProperties: map[string]string{
@@ -169,7 +172,7 @@ func TestTransform(t *testing.T) {
169172
}(),
170173
},
171174
want: datadogV2.HTTPLogItem{
172-
Ddtags: datadog.PtrString(""),
175+
Ddtags: datadog.PtrString("otel_source:test"),
173176
Message: *datadog.PtrString(""),
174177
Service: datadog.PtrString("otlp_col"),
175178
AdditionalProperties: map[string]string{
@@ -202,7 +205,7 @@ func TestTransform(t *testing.T) {
202205
}(),
203206
},
204207
want: datadogV2.HTTPLogItem{
205-
Ddtags: datadog.PtrString(""),
208+
Ddtags: datadog.PtrString("otel_source:test"),
206209
Message: *datadog.PtrString(""),
207210
Service: datadog.PtrString("otlp_col"),
208211
AdditionalProperties: map[string]string{
@@ -235,7 +238,7 @@ func TestTransform(t *testing.T) {
235238
}(),
236239
},
237240
want: datadogV2.HTTPLogItem{
238-
Ddtags: datadog.PtrString(""),
241+
Ddtags: datadog.PtrString("otel_source:test"),
239242
Message: *datadog.PtrString(""),
240243
Service: datadog.PtrString("otlp_col"),
241244
AdditionalProperties: map[string]string{
@@ -268,7 +271,7 @@ func TestTransform(t *testing.T) {
268271
}(),
269272
},
270273
want: datadogV2.HTTPLogItem{
271-
Ddtags: datadog.PtrString(""),
274+
Ddtags: datadog.PtrString("otel_source:test"),
272275
Message: *datadog.PtrString(""),
273276
Service: datadog.PtrString("otlp_col"),
274277
AdditionalProperties: map[string]string{
@@ -301,7 +304,7 @@ func TestTransform(t *testing.T) {
301304
}(),
302305
},
303306
want: datadogV2.HTTPLogItem{
304-
Ddtags: datadog.PtrString(""),
307+
Ddtags: datadog.PtrString("otel_source:test"),
305308
Message: *datadog.PtrString(""),
306309
Service: datadog.PtrString("otlp_col"),
307310
AdditionalProperties: map[string]string{
@@ -336,7 +339,7 @@ func TestTransform(t *testing.T) {
336339
}(),
337340
},
338341
want: datadogV2.HTTPLogItem{
339-
Ddtags: datadog.PtrString(""),
342+
Ddtags: datadog.PtrString("otel_source:test"),
340343
Message: *datadog.PtrString(""),
341344
Service: datadog.PtrString("otlp_col"),
342345
AdditionalProperties: map[string]string{
@@ -371,7 +374,7 @@ func TestTransform(t *testing.T) {
371374
}(),
372375
},
373376
want: datadogV2.HTTPLogItem{
374-
Ddtags: datadog.PtrString(""),
377+
Ddtags: datadog.PtrString("otel_source:test"),
375378
Message: *datadog.PtrString(""),
376379
Service: datadog.PtrString("otlp_col"),
377380
AdditionalProperties: map[string]string{
@@ -403,7 +406,7 @@ func TestTransform(t *testing.T) {
403406
}(),
404407
},
405408
want: datadogV2.HTTPLogItem{
406-
Ddtags: datadog.PtrString("service:otlp_col"),
409+
Ddtags: datadog.PtrString("service:otlp_col,otel_source:test"),
407410
Message: *datadog.PtrString(""),
408411
Service: datadog.PtrString("otlp_col"),
409412
AdditionalProperties: map[string]string{
@@ -432,7 +435,7 @@ func TestTransform(t *testing.T) {
432435
}(),
433436
},
434437
want: datadogV2.HTTPLogItem{
435-
Ddtags: datadog.PtrString(""),
438+
Ddtags: datadog.PtrString("otel_source:test"),
436439
Message: *datadog.PtrString(""),
437440
AdditionalProperties: map[string]string{
438441
"app": "test",
@@ -471,7 +474,7 @@ func TestTransform(t *testing.T) {
471474
}(),
472475
},
473476
want: datadogV2.HTTPLogItem{
474-
Ddtags: datadog.PtrString(""),
477+
Ddtags: datadog.PtrString("otel_source:test"),
475478
Message: *datadog.PtrString(""),
476479
AdditionalProperties: map[string]string{
477480
"root.nest1.nest2": "val",
@@ -495,7 +498,7 @@ func TestTransform(t *testing.T) {
495498
}(),
496499
},
497500
want: datadogV2.HTTPLogItem{
498-
Ddtags: datadog.PtrString(""),
501+
Ddtags: datadog.PtrString("otel_source:test"),
499502
Message: *datadog.PtrString(""),
500503
AdditionalProperties: map[string]string{
501504
"status": "",
@@ -545,7 +548,7 @@ func TestTransform(t *testing.T) {
545548
}(),
546549
},
547550
want: datadogV2.HTTPLogItem{
548-
Ddtags: datadog.PtrString(""),
551+
Ddtags: datadog.PtrString("otel_source:test"),
549552
Message: *datadog.PtrString(""),
550553
AdditionalProperties: map[string]string{
551554
"nest1.nest2.nest3.nest4.nest5.nest6.nest7.nest8.nest9.nest10": "{\"nest11\":{\"nest12\":\"ok\"}}",
@@ -569,7 +572,7 @@ func TestTransform(t *testing.T) {
569572
}(),
570573
},
571574
want: datadogV2.HTTPLogItem{
572-
Ddtags: datadog.PtrString(""),
575+
Ddtags: datadog.PtrString("otel_source:test"),
573576
Message: *datadog.PtrString(""),
574577
AdditionalProperties: map[string]string{
575578
"status": "debug",
@@ -580,9 +583,24 @@ func TestTransform(t *testing.T) {
580583
},
581584
},
582585
}
586+
587+
set := componenttest.NewNopTelemetrySettings()
588+
set.Logger = zaptest.NewLogger(t)
589+
attributesTranslator, err := attributes.NewTranslator(set)
590+
require.NoError(t, err)
591+
translator, err := NewTranslator(set, attributesTranslator, "test")
592+
require.NoError(t, err)
593+
583594
for _, tt := range tests {
584595
t.Run(tt.name, func(t *testing.T) {
585-
got := Transform(tt.args.lr, tt.args.res, testLogger)
596+
logs := plog.NewLogs()
597+
rl := logs.ResourceLogs().AppendEmpty()
598+
tt.args.res.MoveTo(rl.Resource())
599+
tt.args.lr.CopyTo(rl.ScopeLogs().AppendEmpty().LogRecords().AppendEmpty())
600+
601+
payloads := translator.MapLogs(context.Background(), logs)
602+
require.Len(t, payloads, 1)
603+
got := payloads[0]
586604

587605
gs, err := got.MarshalJSON()
588606
if err != nil {

pkg/otlp/logs/translator.go

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,40 +15,82 @@
1515
package logs
1616

1717
import (
18+
"context"
19+
1820
"github.com/DataDog/datadog-api-client-go/v2/api/datadogV2"
21+
"github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/attributes"
22+
"github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/attributes/source"
1923
"go.opentelemetry.io/collector/component"
24+
"go.opentelemetry.io/collector/pdata/pcommon"
2025
"go.opentelemetry.io/collector/pdata/plog"
26+
conventions "go.opentelemetry.io/collector/semconv/v1.6.1"
27+
"go.opentelemetry.io/otel/attribute"
28+
)
29+
30+
var (
31+
signalTypeSet = attribute.NewSet(attribute.String("signal", "logs"))
2132
)
2233

2334
// Translator of OTLP logs to Datadog format
2435
type Translator struct {
25-
set component.TelemetrySettings
26-
otelTag string
36+
set component.TelemetrySettings
37+
attributesTranslator *attributes.Translator
38+
otelTag string
2739
}
2840

2941
// NewTranslator returns a new Translator
30-
func NewTranslator(set component.TelemetrySettings, otelSource string) (*Translator, error) {
42+
func NewTranslator(set component.TelemetrySettings, attributesTranslator *attributes.Translator, otelSource string) (*Translator, error) {
3143
return &Translator{
32-
set: set,
33-
otelTag: "otel_source:" + otelSource,
44+
set: set,
45+
attributesTranslator: attributesTranslator,
46+
otelTag: "otel_source:" + otelSource,
3447
}, nil
3548
}
3649

50+
func (t *Translator) hostNameAndServiceNameFromResource(ctx context.Context, res pcommon.Resource) (host string, service string) {
51+
if src, ok := t.attributesTranslator.ResourceToSource(ctx, res, signalTypeSet); ok && src.Kind == source.HostnameKind {
52+
host = src.Identifier
53+
}
54+
if s, ok := res.Attributes().Get(conventions.AttributeServiceName); ok {
55+
service = s.AsString()
56+
}
57+
return host, service
58+
}
59+
60+
func (t *Translator) hostFromAttributes(ctx context.Context, attrs pcommon.Map) string {
61+
if src, ok := t.attributesTranslator.AttributesToSource(ctx, attrs); ok && src.Kind == source.HostnameKind {
62+
return src.Identifier
63+
}
64+
return ""
65+
}
66+
3767
// MapLogs from OTLP format to Datadog format.
38-
func (t *Translator) MapLogs(ld plog.Logs) []datadogV2.HTTPLogItem {
68+
func (t *Translator) MapLogs(ctx context.Context, ld plog.Logs) []datadogV2.HTTPLogItem {
3969
rsl := ld.ResourceLogs()
4070
var payloads []datadogV2.HTTPLogItem
4171
for i := 0; i < rsl.Len(); i++ {
4272
rl := rsl.At(i)
4373
sls := rl.ScopeLogs()
4474
res := rl.Resource()
75+
host, service := t.hostNameAndServiceNameFromResource(ctx, res)
4576
for j := 0; j < sls.Len(); j++ {
4677
sl := sls.At(j)
4778
lsl := sl.LogRecords()
4879
// iterate over Logs
4980
for k := 0; k < lsl.Len(); k++ {
5081
log := lsl.At(k)
51-
payload := Transform(log, res, t.set.Logger)
82+
// HACK: Check for host and service in log record attributes
83+
// This is not aligned with the specification and will be removed in the future.
84+
if host == "" {
85+
host = t.hostFromAttributes(ctx, log.Attributes())
86+
}
87+
if service == "" {
88+
if s, ok := log.Attributes().Get(conventions.AttributeServiceName); ok {
89+
service = s.AsString()
90+
}
91+
}
92+
93+
payload := transform(log, host, service, res, t.set.Logger)
5294
ddtags := payload.GetDdtags()
5395
if ddtags != "" {
5496
payload.SetDdtags(ddtags + "," + t.otelTag)

0 commit comments

Comments
 (0)