Skip to content

Commit

Permalink
support obfuscation in datadogconnector
Browse files Browse the repository at this point in the history
  • Loading branch information
jackgopack4 committed Jan 23, 2025
1 parent 4542bbf commit b9b4121
Show file tree
Hide file tree
Showing 9 changed files with 259 additions and 91 deletions.
32 changes: 32 additions & 0 deletions .chloggen/datadogconnector-add-stats-obfuscation.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Use this changelog template to create an entry for release notes.

# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: enhancement

# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
component: datadogconnector

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Support obfuscating sql queries in APM stats

# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
issues: [35401]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext: |
Ensure that feature flags "enable_receive_resource_spans_v2" and "enable_operation_and_resource_name_logic_v2"
are both enabled on Datadog Exporter and Datadog Connector so that span attributes are properly
mapped to span type and span resource in Datadog APM; otherwise spans and apm stats may not be
obfuscated and attributes on stats payloads may not match traces.
see https://docs.datadoghq.com/opentelemetry/schema_semantics/semantic_mapping/?tab=datadogexporter#mapping-opentelemetry-database-system-type-to-datadog-span-type

# If your change doesn't affect end users or the exported elements of any package,
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
# Optional: The change log or logs in which this entry should be included.
# e.g. '[user]' or '[user, api]'
# Include 'user' if the change is relevant to end users.
# Include 'api' if there is a change to a library API.
# Default: '[user]'
change_logs: [user]
15 changes: 14 additions & 1 deletion connector/datadogconnector/connector_native.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"time"

"github.com/DataDog/datadog-agent/comp/otelcol/otlp/components/statsprocessor"
"github.com/DataDog/datadog-agent/pkg/obfuscate"
pb "github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace"
"github.com/DataDog/datadog-agent/pkg/trace/config"
"github.com/DataDog/datadog-agent/pkg/trace/stats"
Expand Down Expand Up @@ -48,6 +49,10 @@ type traceToMetricConnectorNative struct {
// resulting from ingested traces.
statsout chan *pb.StatsPayload

// obfuscator is used to obfuscate sensitive data from various span
// tags based on their type.
obfuscator *obfuscate.Obfuscator

// exit specifies the exit channel, which will be closed upon shutdown.
exit chan struct{}

Expand All @@ -73,6 +78,10 @@ func newTraceToMetricConnectorNative(set component.TelemetrySettings, cfg compon
}

tcfg := getTraceAgentCfg(set.Logger, cfg.(*Config).Traces, attributesTranslator)
oconf := tcfg.Obfuscation.Export(tcfg)
oconf.Statsd = metricsClient
oconf.Redis.Enabled = true

return &traceToMetricConnectorNative{
logger: set.Logger,
translator: trans,
Expand All @@ -82,6 +91,7 @@ func newTraceToMetricConnectorNative(set component.TelemetrySettings, cfg compon
concentrator: stats.NewConcentrator(tcfg, statsWriter, time.Now(), metricsClient),
statsout: statsout,
metricsConsumer: metricsConsumer,
obfuscator: obfuscate.NewObfuscator(oconf),
exit: make(chan struct{}),
}, nil
}
Expand All @@ -103,6 +113,9 @@ func (c *traceToMetricConnectorNative) Shutdown(context.Context) error {
return nil
}
c.logger.Info("Shutting down datadog connector")
c.logger.Info("Stopping obfuscator and concentrator")
// stop the obfuscator and concentrator and wait for the run loop to exit
c.obfuscator.Stop()
c.logger.Info("Stopping concentrator")
// stop the concentrator and wait for the run loop to exit
c.concentrator.Stop()
Expand All @@ -118,7 +131,7 @@ func (c *traceToMetricConnectorNative) Capabilities() consumer.Capabilities {
}

func (c *traceToMetricConnectorNative) ConsumeTraces(_ context.Context, traces ptrace.Traces) error {
inputs := stats.OTLPTracesToConcentratorInputs(traces, c.tcfg, c.ctagKeys, c.peerTagKeys)
inputs := stats.OTLPTracesToConcentratorInputsWithObfuscation(traces, c.tcfg, c.ctagKeys, c.peerTagKeys, c.obfuscator)
for _, input := range inputs {
c.concentrator.Add(input)
}
Expand Down
73 changes: 73 additions & 0 deletions connector/datadogconnector/connector_native_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,3 +268,76 @@ func testMeasuredAndClientKindNative(t *testing.T, enableOperationAndResourceNam
t.Errorf("Diff between APM stats -want +got:\n%v", diff)
}
}
func TestObfuscate(t *testing.T) {
cfg := NewFactory().CreateDefaultConfig().(*Config)
cfg.Traces.BucketInterval = time.Second
connector, metricsSink := creteConnectorNativeWithCfg(t, cfg)
err := connector.Start(context.Background(), componenttest.NewNopHost())
require.NoError(t, err)
defer func() {
require.NoError(t, connector.Shutdown(context.Background()))
}()

td := ptrace.NewTraces()
res := td.ResourceSpans().AppendEmpty().Resource()
res.Attributes().PutStr("service.name", "svc")
res.Attributes().PutStr(semconv.AttributeDeploymentEnvironmentName, "my-env")

ss := td.ResourceSpans().At(0).ScopeSpans().AppendEmpty().Spans()
s := ss.AppendEmpty()
s.SetName("name")
s.SetKind(ptrace.SpanKindClient)
s.SetTraceID(testTraceID)
s.SetSpanID(testSpanID1)
s.Attributes().PutStr("span.type", "sql")
s.Attributes().PutStr("operation.name", "sql_query")
s.Attributes().PutStr("resource.name", "SELECT username FROM users WHERE id = 123") // id value 123 should be obfuscated

err = connector.ConsumeTraces(context.Background(), td)
require.NoError(t, err)

timeout := time.Now().Add(1 * time.Minute)
for time.Now().Before(timeout) {
if len(metricsSink.AllMetrics()) > 0 {
break
}
time.Sleep(100 * time.Millisecond)
}

metrics := metricsSink.AllMetrics()
require.Len(t, metrics, 1)

ch := make(chan []byte, 100)
tr := newTranslatorWithStatsChannel(t, zap.NewNop(), ch)
_, err = tr.MapMetrics(context.Background(), metrics[0], nil)
require.NoError(t, err)
msg := <-ch
sp := &pb.StatsPayload{}

err = proto.Unmarshal(msg, sp)
require.NoError(t, err)
assert.Len(t, sp.Stats, 1)
assert.Len(t, sp.Stats[0].Stats, 1)
assert.Equal(t, "my-env", sp.Stats[0].Env)
assert.Len(t, sp.Stats[0].Stats[0].Stats, 1)
cgss := sp.Stats[0].Stats[0].Stats
expected := []*pb.ClientGroupedStats{
{
Service: "svc",
Name: "sql_query",
Resource: "SELECT username FROM users WHERE id = ?",
Type: "sql",
Hits: 1,
TopLevelHits: 1,
SpanKind: "client",
IsTraceRoot: pb.Trilean_TRUE,
},
}
if diff := cmp.Diff(
cgss,
expected,
protocmp.Transform(),
protocmp.IgnoreFields(&pb.ClientGroupedStats{}, "duration", "okSummary", "errorSummary")); diff != "" {
t.Errorf("Diff between APM stats -want +got:\n%v", diff)
}
}
24 changes: 13 additions & 11 deletions connector/datadogconnector/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ go 1.22.0
require (
github.com/DataDog/datadog-agent/comp/otelcol/otlp/components/metricsclient v0.61.0
github.com/DataDog/datadog-agent/comp/otelcol/otlp/components/statsprocessor v0.61.0
github.com/DataDog/datadog-agent/pkg/proto v0.63.0-devel
github.com/DataDog/datadog-agent/pkg/trace v0.61.0
github.com/DataDog/datadog-agent/pkg/obfuscate v0.63.0-devel.0.20250123185937-1feb84b482c8
github.com/DataDog/datadog-agent/pkg/proto v0.63.0-devel.0.20250123185937-1feb84b482c8
github.com/DataDog/datadog-agent/pkg/trace v0.63.0-devel.0.20250123185937-1feb84b482c8
github.com/DataDog/datadog-go/v5 v5.6.0
github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/attributes v0.24.0
github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/metrics v0.24.0
Expand Down Expand Up @@ -49,6 +50,7 @@ require (
github.com/DataDog/datadog-agent/comp/core/hostname/hostnameinterface v0.61.0 // indirect
github.com/DataDog/datadog-agent/comp/core/log/def v0.61.0 // indirect
github.com/DataDog/datadog-agent/comp/core/secrets v0.61.0 // indirect
github.com/DataDog/datadog-agent/comp/core/tagger/origindetection v0.0.0-20241217122454-175edb6c74f2 // indirect
github.com/DataDog/datadog-agent/comp/core/telemetry v0.61.0 // indirect
github.com/DataDog/datadog-agent/comp/def v0.61.0 // indirect
github.com/DataDog/datadog-agent/comp/logs/agent/config v0.61.0 // indirect
Expand Down Expand Up @@ -78,7 +80,6 @@ require (
github.com/DataDog/datadog-agent/pkg/logs/sources v0.61.0 // indirect
github.com/DataDog/datadog-agent/pkg/logs/status/statusinterface v0.61.0 // indirect
github.com/DataDog/datadog-agent/pkg/logs/status/utils v0.61.0 // indirect
github.com/DataDog/datadog-agent/pkg/obfuscate v0.61.0 // indirect
github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.61.0 // indirect
github.com/DataDog/datadog-agent/pkg/status/health v0.61.0 // indirect
github.com/DataDog/datadog-agent/pkg/telemetry v0.61.0 // indirect
Expand All @@ -89,7 +90,7 @@ require (
github.com/DataDog/datadog-agent/pkg/util/fxutil v0.61.0 // indirect
github.com/DataDog/datadog-agent/pkg/util/hostname/validate v0.61.0 // indirect
github.com/DataDog/datadog-agent/pkg/util/http v0.61.0 // indirect
github.com/DataDog/datadog-agent/pkg/util/log v0.61.0 // indirect
github.com/DataDog/datadog-agent/pkg/util/log v0.63.0-devel.0.20250123185937-1feb84b482c8 // indirect
github.com/DataDog/datadog-agent/pkg/util/optional v0.61.0 // indirect
github.com/DataDog/datadog-agent/pkg/util/pointer v0.61.0 // indirect
github.com/DataDog/datadog-agent/pkg/util/scrubber v0.61.0 // indirect
Expand All @@ -101,7 +102,7 @@ require (
github.com/DataDog/datadog-agent/pkg/version v0.61.0 // indirect
github.com/DataDog/datadog-api-client-go/v2 v2.34.0 // indirect
github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240816154533-f7f9beb53a42 // indirect
github.com/DataDog/go-sqllexer v0.0.16 // indirect
github.com/DataDog/go-sqllexer v0.0.20 // indirect
github.com/DataDog/go-tuf v1.1.0-0.5.2 // indirect
github.com/DataDog/gohai v0.0.0-20230524154621-4316413895ee // indirect
github.com/DataDog/opentelemetry-mapping-go/pkg/inframetadata v0.24.0 // indirect
Expand Down Expand Up @@ -136,7 +137,7 @@ require (
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 // indirect
github.com/containerd/cgroups/v3 v3.0.3 // indirect
github.com/containerd/cgroups/v3 v3.0.4 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/docker/go-units v0.5.0 // indirect
Expand All @@ -158,10 +159,10 @@ require (
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/goccy/go-json v0.10.4 // indirect
github.com/godbus/dbus/v5 v5.0.6 // indirect
github.com/godbus/dbus/v5 v5.1.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/golang/mock v1.7.0-rc.1 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/gnostic-models v0.6.8 // indirect
Expand Down Expand Up @@ -195,6 +196,7 @@ require (
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/moby/sys/userns v0.1.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
Expand All @@ -208,10 +210,10 @@ require (
github.com/open-telemetry/opentelemetry-collector-contrib/internal/metadataproviders v0.118.0 // indirect
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl v0.118.0 // indirect
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/resourcetotelemetry v0.118.0 // indirect
github.com/opencontainers/runtime-spec v1.1.0-rc.3 // indirect
github.com/opencontainers/runtime-spec v1.2.0 // indirect
github.com/openshift/api v3.9.0+incompatible // indirect
github.com/openshift/client-go v0.0.0-20210521082421-73d9475a9142 // indirect
github.com/outcaste-io/ristretto v0.2.1 // indirect
github.com/outcaste-io/ristretto v0.2.3 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect
github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c // indirect
github.com/pierrec/lz4/v4 v4.1.22 // indirect
Expand All @@ -224,7 +226,7 @@ require (
github.com/prometheus/common v0.62.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
github.com/rs/cors v1.11.1 // indirect
github.com/secure-systems-lab/go-securesystemslib v0.7.0 // indirect
github.com/secure-systems-lab/go-securesystemslib v0.8.0 // indirect
github.com/shirou/gopsutil/v3 v3.24.5 // indirect
github.com/shirou/gopsutil/v4 v4.24.12 // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect
Expand Down
Loading

0 comments on commit b9b4121

Please sign in to comment.