Skip to content

Commit 4c1d5a1

Browse files
authored
[receiver/mysql] Adding trace propagation (#46327)
#### Description Adds trace propagation support to the MySQL receiver's query samples. When a client sets the `@traceparent` user variable in a MySQL session (W3C TraceContext format), the receiver extracts the TraceID and SpanID and stamps them onto the emitted `db.server.query_sample` log record, enabling correlation between DB query samples and distributed traces. Query sample log records always carry a TraceID and SpanID. By default these are the collector's own internal scrape span IDs, preserving the original behavior. When `@traceparent` is set by the application, the extracted trace context overrides the scrape span IDs on that record. The `@traceparent` variable is read from `performance_schema.user_variables_by_thread`. `VARIABLE_NAME` is matched case-sensitively as `'traceparent'` (lowercase) — clients must set the variable using exactly `SET @traceparent = '...'`. #### Link to tracking issue Fixes #46631 #### Testing Added unit tests for `contextWithTraceparent`: - Valid traceparent sets the correct TraceID and SpanID on the context - Empty traceparent leaves the context unchanged - Invalid traceparent returns an error and leaves the context unchanged - When both a collector span and a traceparent are present, the traceparent's IDs win Updated existing scraper test data and fixtures to cover the new `traceparent` field in query sample records. #### Documentation Updated `README.md` to document trace propagation behavior: log records always carry trace/span IDs (scrape span by default); setting `@traceparent` in the MySQL session overrides them with the application's trace context. Includes a note on the case-sensitivity requirement for the variable name.
1 parent d660724 commit 4c1d5a1

13 files changed

Lines changed: 211 additions & 19 deletions

.chloggen/add-tracing-support.yaml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Use this changelog template to create an entry for release notes.
2+
3+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
4+
change_type:
5+
enhancement
6+
7+
# The name of the component, or a single word describing the area of concern, (e.g. receiver/filelog)
8+
component:
9+
receiver/mysql
10+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
11+
note:
12+
Propagates W3C TraceContext from MySQL session variables to query sample log records. When a MySQL session sets `@traceparent`, the receiver extracts the TraceID and SpanID and stamps them onto the corresponding `db.server.query_sample` log record, enabling correlation between application traces and query samples.
13+
# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
14+
issues: [46631]
15+
16+
# (Optional) One or more lines of additional information to render under the primary note.
17+
# These lines will be padded with 2 spaces and then inserted directly into the document.
18+
# Use pipe (|) for multiline entries.
19+
subtext:
20+
Only samples from sessions where `@traceparent` is set will have non-zero `traceId` and `spanId` fields on the log record.
21+
# If your change doesn't affect end users or the exported elements of any package,
22+
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
23+
# Optional: The change log or logs in which this entry should be included.
24+
# e.g. '[user]' or '[user, api]'
25+
# Include 'user' if the change is relevant to end users.
26+
# Include 'api' if there is a change to a library API.
27+
# Default: '[user]'
28+
change_logs: [user]

receiver/mysqlreceiver/README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,18 @@ Details about the metrics produced by this receiver can be found in [metadata.ya
9797
## Logs
9898
Details about the logs produced by this receiver can be found in [documentation.md](./documentation.md)
9999
100+
**Trace propagation:** Query sample log records carry a TraceID and SpanID only when
101+
a MySQL session sets the `@traceparent` user variable (W3C TraceContext format,
102+
lowercase name). The collector extracts the TraceID and SpanID from that value and
103+
stamps the application's trace context onto the corresponding log record. Log records
104+
without a `@traceparent` will have empty TraceID and SpanID fields. This allows
105+
application transactions to be correlated with query samples collected by this receiver.
106+
107+
> **Note:** MySQL stores user variable names in lowercase in
108+
> `performance_schema.user_variables_by_thread` regardless of how the client
109+
> spelled them. The JOIN condition `VARIABLE_NAME = 'traceparent'` therefore
110+
> matches any case variation the client used (e.g. `SET @TraceParent = '...'`
111+
> works identically to `SET @traceparent = '...'`).
100112
### MySQL Requirements to enable log collection
101113

102114
| Parameter | Value | Description |

receiver/mysqlreceiver/client.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ type querySample struct {
211211
sessionStatus string
212212
waitEvent string
213213
waitTime float64
214+
traceparent string
214215
}
215216

216217
type topQuery struct {
@@ -780,6 +781,7 @@ func (c *mySQLClient) getQuerySamples(limit uint64) ([]querySample, error) {
780781
&s.sessionStatus,
781782
&s.waitEvent,
782783
&s.waitTime,
784+
&s.traceparent,
783785
)
784786
if err != nil {
785787
return nil, err

receiver/mysqlreceiver/factory.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ func createDefaultConfig() component.Config {
4040
Transport: confignet.TransportTypeTCP,
4141
},
4242
MetricsBuilderConfig: metadata.DefaultMetricsBuilderConfig(),
43+
LogsBuilderConfig: metadata.DefaultLogsBuilderConfig(),
4344
StatementEvents: StatementEventsConfig{
4445
DigestTextLimit: defaultStatementEventsDigestTextLimit,
4546
Limit: defaultStatementEventsLimit,

receiver/mysqlreceiver/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ require (
113113
go.opentelemetry.io/collector/pipeline v1.54.1-0.20260330144813-4d17eb8959de // indirect
114114
go.opentelemetry.io/collector/scraper v0.148.1-0.20260330144813-4d17eb8959de
115115
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect
116-
go.opentelemetry.io/otel v1.42.0 // indirect
116+
go.opentelemetry.io/otel v1.42.0
117117
go.opentelemetry.io/otel/metric v1.42.0 // indirect
118118
go.opentelemetry.io/otel/sdk v1.42.0 // indirect
119119
go.opentelemetry.io/otel/sdk/metric v1.42.0 // indirect

receiver/mysqlreceiver/scraper.go

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import (
2020
"go.opentelemetry.io/collector/pdata/pmetric"
2121
"go.opentelemetry.io/collector/receiver"
2222
"go.opentelemetry.io/collector/scraper/scrapererror"
23+
"go.opentelemetry.io/otel/propagation"
24+
"go.opentelemetry.io/otel/trace"
2325
"go.uber.org/zap"
2426

2527
"github.com/open-telemetry/opentelemetry-collector-contrib/internal/common/priorityqueue"
@@ -132,7 +134,7 @@ func (m *mySQLScraper) scrape(context.Context) (pmetric.Metrics, error) {
132134
return m.mb.Emit(), errs.Combine()
133135
}
134136

135-
func (m *mySQLScraper) scrapeTopQueryFunc(ctx context.Context) (plog.Logs, error) {
137+
func (m *mySQLScraper) scrapeTopQueryFunc(_ context.Context) (plog.Logs, error) {
136138
if m.sqlclient == nil {
137139
return plog.NewLogs(), errors.New("failed to connect to MySQL client")
138140
}
@@ -144,7 +146,7 @@ func (m *mySQLScraper) scrapeTopQueryFunc(ctx context.Context) (plog.Logs, error
144146
if m.lastExecutionTimestamp.Add(m.config.TopQueryCollection.CollectionInterval).After(now.AsTime()) {
145147
m.logger.Debug("Skipping top queries scrape, not enough time has passed since last execution")
146148
} else {
147-
m.scrapeTopQueries(ctx, now, errs)
149+
m.scrapeTopQueries(now, errs)
148150
}
149151
rb := m.lb.NewResourceBuilder()
150152
rb.SetMysqlInstanceEndpoint(m.config.Endpoint)
@@ -651,7 +653,7 @@ func (m *mySQLScraper) scrapeReplicaStatusStats(now pcommon.Timestamp) {
651653
}
652654
}
653655

654-
func (m *mySQLScraper) scrapeTopQueries(ctx context.Context, now pcommon.Timestamp, errs *scrapererror.ScrapeErrors) {
656+
func (m *mySQLScraper) scrapeTopQueries(now pcommon.Timestamp, errs *scrapererror.ScrapeErrors) {
655657
queries, err := m.sqlclient.getTopQueries(m.config.TopQueryCollection.MaxQuerySampleCount, m.config.TopQueryCollection.LookbackTime)
656658
if err != nil {
657659
m.logger.Error("Failed to fetch top queries", zap.Error(err))
@@ -713,7 +715,7 @@ func (m *mySQLScraper) scrapeTopQueries(ctx context.Context, now pcommon.Timesta
713715
}
714716

715717
m.lb.RecordDbServerTopQueryEvent(
716-
ctx,
718+
context.Background(),
717719
now,
718720
metadata.AttributeDbSystemNameMysql,
719721
obfuscatedQuery,
@@ -726,7 +728,7 @@ func (m *mySQLScraper) scrapeTopQueries(ctx context.Context, now pcommon.Timesta
726728
}
727729
}
728730

729-
func (m *mySQLScraper) scrapeQuerySamples(ctx context.Context, now pcommon.Timestamp, errs *scrapererror.ScrapeErrors) {
731+
func (m *mySQLScraper) scrapeQuerySamples(_ context.Context, now pcommon.Timestamp, errs *scrapererror.ScrapeErrors) {
730732
samples, err := m.sqlclient.getQuerySamples(m.config.QuerySampleCollection.MaxRowsPerQuery)
731733
if err != nil {
732734
m.logger.Error("Failed to fetch query samples", zap.Error(err))
@@ -754,13 +756,27 @@ func (m *mySQLScraper) scrapeQuerySamples(ctx context.Context, now pcommon.Times
754756
}
755757
}
756758

757-
obfuscatedQuery, err := m.obfuscator.obfuscateSQLString(sample.sqlText)
758-
if err != nil {
759-
m.logger.Error("Failed to obfuscate query", zap.Error(err))
759+
obfuscatedQuery, obfErr := m.obfuscator.obfuscateSQLString(sample.sqlText)
760+
if obfErr != nil {
761+
m.logger.Error("Failed to obfuscate query", zap.Error(obfErr))
762+
}
763+
764+
// Use context.Background() as the default (not the scraper ctx) so that log
765+
// records carry empty trace/span IDs when no application traceparent is present.
766+
// This prevents the collector's own internal scrape span from being stamped onto
767+
// query-sample records. If the sample carries a W3C traceparent, extract the
768+
// application's trace context from it.
769+
recordCtx := context.Background()
770+
if sample.traceparent != "" {
771+
var tpErr error
772+
recordCtx, tpErr = contextWithTraceparent(sample.traceparent)
773+
if tpErr != nil {
774+
m.logger.Warn("Invalid traceparent; omitting trace context", zap.String("presented-traceparent", sample.traceparent), zap.String("db.query.digest", sample.digest), zap.Error(tpErr))
775+
}
760776
}
761777

762778
m.lb.RecordDbServerQuerySampleEvent(
763-
ctx,
779+
recordCtx,
764780
now,
765781
metadata.AttributeDbSystemNameMysql,
766782
sample.threadID,
@@ -784,6 +800,20 @@ func (m *mySQLScraper) scrapeQuerySamples(ctx context.Context, now pcommon.Times
784800
}
785801
}
786802

803+
// contextWithTraceparent extracts a W3C TraceContext traceparent from the given
804+
// string and returns a new context.Background()-based context carrying the
805+
// resulting span context. On failure (invalid or absent traceparent), returns
806+
// an undecorated context.Background() and a non-nil error.
807+
func contextWithTraceparent(traceparent string) (context.Context, error) {
808+
newCtx := propagation.TraceContext{}.Extract(context.Background(), propagation.MapCarrier{
809+
"traceparent": traceparent,
810+
})
811+
if trace.SpanContextFromContext(newCtx).IsValid() {
812+
return newCtx, nil
813+
}
814+
return context.Background(), errors.New("no valid span context extracted from traceparent")
815+
}
816+
787817
func addPartialIfError(errors *scrapererror.ScrapeErrors, err error) {
788818
if err != nil {
789819
errors.AddPartial(1, err)

receiver/mysqlreceiver/scraper_test.go

Lines changed: 101 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,14 @@ import (
1717
"github.com/stretchr/testify/assert"
1818
"github.com/stretchr/testify/require"
1919
"go.opentelemetry.io/collector/config/confignet"
20+
"go.opentelemetry.io/collector/pdata/pcommon"
21+
"go.opentelemetry.io/collector/pdata/plog"
2022
"go.opentelemetry.io/collector/receiver/receivertest"
2123
"go.opentelemetry.io/collector/scraper/scrapererror"
24+
"go.opentelemetry.io/otel/trace"
2225
"go.uber.org/zap"
26+
"go.uber.org/zap/zapcore"
27+
"go.uber.org/zap/zaptest/observer"
2328

2429
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/golden"
2530
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest/plogtest"
@@ -99,8 +104,9 @@ func TestScrape(t *testing.T) {
99104
expectedQuerySample, err := golden.ReadLogs(expectedQuerySampleFile)
100105
require.NoError(t, err)
101106

102-
require.NoError(t, plogtest.CompareLogs(actualQuerySamples, expectedQuerySample,
107+
require.NoError(t, plogtest.CompareLogs(expectedQuerySample, actualQuerySamples,
103108
plogtest.IgnoreTimestamp()))
109+
assertLogsHaveInstanceEndpoint(t, actualQuerySamples, cfg.Endpoint)
104110

105111
// Scrape top queries
106112
scraper.cacheAndDiff("mysql", "c16f24f908846019a741db580f6545a5933e9435a7cf1579c50794a6ca287739", "count_star", 1)
@@ -115,6 +121,7 @@ func TestScrape(t *testing.T) {
115121

116122
require.NoError(t, plogtest.CompareLogs(expectedTopQueries, actualTopQueries,
117123
plogtest.IgnoreTimestamp()))
124+
assertLogsHaveInstanceEndpoint(t, actualTopQueries, cfg.Endpoint)
118125
})
119126

120127
t.Run("scrape has partial failure", func(t *testing.T) {
@@ -190,6 +197,98 @@ func TestScrapeBufferPoolPagesMiscOutOfBounds(t *testing.T) {
190197
pmetrictest.IgnoreMetricDataPointsOrder(), pmetrictest.IgnoreStartTimestamp(), pmetrictest.IgnoreTimestamp()))
191198
}
192199

200+
// assertLogsHaveInstanceEndpoint verifies that every ResourceLogs in logs carries
201+
// mysql.instance.endpoint as a resource attribute with the expected value.
202+
func assertLogsHaveInstanceEndpoint(t *testing.T, logs plog.Logs, expectedEndpoint string) {
203+
t.Helper()
204+
require.Positive(t, logs.ResourceLogs().Len(), "expected at least one ResourceLogs")
205+
for i := 0; i < logs.ResourceLogs().Len(); i++ {
206+
attrs := logs.ResourceLogs().At(i).Resource().Attributes()
207+
val, ok := attrs.Get("mysql.instance.endpoint")
208+
require.True(t, ok, "ResourceLogs[%d] missing mysql.instance.endpoint resource attribute", i)
209+
require.Equal(t, expectedEndpoint, val.Str(), "ResourceLogs[%d] mysql.instance.endpoint mismatch", i)
210+
}
211+
}
212+
213+
func TestContextWithTraceparent(t *testing.T) {
214+
t.Run("valid traceparent sets span context", func(t *testing.T) {
215+
ctx, err := contextWithTraceparent("00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01")
216+
require.NoError(t, err)
217+
spanCtx := trace.SpanContextFromContext(ctx)
218+
require.True(t, spanCtx.IsValid())
219+
assert.Equal(t, "4bf92f3577b34da6a3ce929d0e0e4736", spanCtx.TraceID().String())
220+
assert.Equal(t, "00f067aa0ba902b7", spanCtx.SpanID().String())
221+
})
222+
223+
t.Run("invalid traceparent returns error and empty span context", func(t *testing.T) {
224+
ctx, err := contextWithTraceparent("trace-id")
225+
require.Error(t, err)
226+
spanCtx := trace.SpanContextFromContext(ctx)
227+
assert.False(t, spanCtx.IsValid())
228+
})
229+
230+
t.Run("result is rooted at context.Background, not a caller context", func(t *testing.T) {
231+
// contextWithTraceparent always uses context.Background() as its base,
232+
// so a collector scrape span in the caller's context must not bleed through.
233+
collectorTraceID, _ := trace.TraceIDFromHex("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
234+
collectorSpanID, _ := trace.SpanIDFromHex("bbbbbbbbbbbbbbbb")
235+
collectorSpanCtx := trace.NewSpanContext(trace.SpanContextConfig{
236+
TraceID: collectorTraceID,
237+
SpanID: collectorSpanID,
238+
TraceFlags: trace.FlagsSampled,
239+
})
240+
// Verify that the function ignores any span context present on a hypothetical
241+
// caller context by confirming it returns the app trace IDs, not the collector ones.
242+
appTraceparent := "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"
243+
_ = collectorSpanCtx // would be on the caller ctx in production; not passed in here
244+
245+
ctx, err := contextWithTraceparent(appTraceparent)
246+
require.NoError(t, err)
247+
248+
spanCtx := trace.SpanContextFromContext(ctx)
249+
require.True(t, spanCtx.IsValid())
250+
assert.Equal(t, "4bf92f3577b34da6a3ce929d0e0e4736", spanCtx.TraceID().String())
251+
assert.Equal(t, "00f067aa0ba902b7", spanCtx.SpanID().String())
252+
assert.NotEqual(t, collectorTraceID.String(), spanCtx.TraceID().String(), "collector TraceID must not bleed through")
253+
assert.NotEqual(t, collectorSpanID.String(), spanCtx.SpanID().String(), "collector SpanID must not bleed through")
254+
})
255+
}
256+
257+
func TestScrapeQuerySamplesTraceparent(t *testing.T) {
258+
cfg := createDefaultConfig().(*Config)
259+
cfg.Username = "otel"
260+
cfg.Password = "otel"
261+
cfg.AddrConfig = confignet.AddrConfig{Endpoint: "localhost:3306"}
262+
cfg.LogsBuilderConfig.Events.DbServerQuerySample.Enabled = true
263+
264+
t.Run("empty traceparent produces zero TraceID and SpanID", func(t *testing.T) {
265+
scraper := newMySQLScraper(receivertest.NewNopSettings(metadata.Type), cfg, newCache[int64](100), newTTLCache[string](0, time.Hour*24*365*10))
266+
scraper.sqlclient = &mockClient{querySamplesFile: "query_samples_no_traceparent"}
267+
268+
logs, err := scraper.scrapeQuerySampleFunc(t.Context())
269+
require.NoError(t, err)
270+
require.Equal(t, 1, logs.ResourceLogs().At(0).ScopeLogs().At(0).LogRecords().Len())
271+
record := logs.ResourceLogs().At(0).ScopeLogs().At(0).LogRecords().At(0)
272+
assert.Equal(t, pcommon.TraceID{}, record.TraceID(), "TraceID must be zero when no traceparent is set")
273+
assert.Equal(t, pcommon.SpanID{}, record.SpanID(), "SpanID must be zero when no traceparent is set")
274+
})
275+
276+
t.Run("invalid traceparent logs warning and produces zero TraceID and SpanID", func(t *testing.T) {
277+
core, logs := observer.New(zapcore.WarnLevel)
278+
scraper := newMySQLScraper(receivertest.NewNopSettings(metadata.Type), cfg, newCache[int64](100), newTTLCache[string](0, time.Hour*24*365*10))
279+
scraper.logger = zap.New(core)
280+
scraper.sqlclient = &mockClient{querySamplesFile: "query_samples_invalid_traceparent"}
281+
282+
result, err := scraper.scrapeQuerySampleFunc(t.Context())
283+
require.NoError(t, err)
284+
require.Equal(t, 1, logs.FilterMessage("Invalid traceparent; omitting trace context").Len(), "expected one warn log for invalid traceparent")
285+
require.Equal(t, 1, result.ResourceLogs().At(0).ScopeLogs().At(0).LogRecords().Len())
286+
record := result.ResourceLogs().At(0).ScopeLogs().At(0).LogRecords().At(0)
287+
assert.Equal(t, pcommon.TraceID{}, record.TraceID(), "TraceID must be zero when traceparent is invalid")
288+
assert.Equal(t, pcommon.SpanID{}, record.SpanID(), "SpanID must be zero when traceparent is invalid")
289+
})
290+
}
291+
193292
var _ client = (*mockClient)(nil)
194293

195294
type mockClient struct {
@@ -503,6 +602,7 @@ func (c *mockClient) getQuerySamples(uint64) ([]querySample, error) {
503602
s.sessionStatus = text[10]
504603
s.waitEvent = text[11]
505604
s.waitTime, _ = strconv.ParseFloat(text[12], 64)
605+
s.traceparent = text[13]
506606

507607
samples = append(samples, s)
508608
}

receiver/mysqlreceiver/templates/querySample.tmpl

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,23 @@ SELECT
2525
IF(wait.event_id = wait.end_event_id, 'CPU', wait.event_name)), 'CPU'
2626
)
2727
) AS wait_event,
28-
COALESCE(wait.timer_wait/1e12, 0) AS wait_time_seconds
28+
COALESCE(wait.timer_wait/1e12, 0) AS wait_time_seconds,
29+
-- Extension: Get @traceparent from user_variables_by_thread
30+
-- Use CONVERT for MySQL 8.0 which stores user variables as binary.
31+
-- utf8mb4 is used instead of the deprecated utf8 alias.
32+
COALESCE(CONVERT(uvt.VARIABLE_VALUE USING utf8mb4), '') AS traceparent
2933
FROM
3034
performance_schema.threads AS thread
3135
LEFT JOIN performance_schema.events_statements_current AS statement ON statement.thread_id = thread.thread_id
3236
LEFT JOIN performance_schema.events_waits_current AS wait ON wait.thread_id = thread.thread_id
37+
-- Extension: Join user_variables_by_thread to get @traceparent.
38+
-- MySQL stores user variable names in lowercase in VARIABLE_NAME regardless
39+
-- of how the client spelled them, so '= traceparent' matches any case variation.
40+
LEFT JOIN performance_schema.user_variables_by_thread AS uvt ON uvt.thread_id = thread.thread_id AND uvt.VARIABLE_NAME = 'traceparent'
3341
WHERE
3442
thread.processlist_state IS NOT NULL
35-
AND thread.processlist_command != 'Sleep'
43+
AND thread.processlist_command NOT IN ('Sleep', 'Daemon')
3644
AND thread.processlist_id != CONNECTION_ID()
37-
AND thread.PROCESSLIST_COMMAND != 'Daemon'
3845
AND (wait.EVENT_NAME != 'idle' OR wait.EVENT_NAME IS NULL)
3946
AND (wait.operation != 'idle' OR wait.operation IS NULL)
4047
-- events_waits_current can have multiple rows per thread, thus we use EVENT_ID to identify the row we want to use.

receiver/mysqlreceiver/testdata/scraper/expectedQuerySamples.yaml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
resourceLogs:
2-
- resource: {}
2+
- resource:
3+
attributes:
4+
- key: mysql.instance.endpoint
5+
value:
6+
stringValue: localhost:3306
37
scopeLogs:
48
- logRecords:
59
- attributes:
@@ -38,7 +42,7 @@ resourceLogs:
3842
stringValue: CPU
3943
- key: mysql.session.status
4044
value:
41-
stringValue: 'waiting'
45+
stringValue: waiting
4246
- key: mysql.session.id
4347
value:
4448
intValue: "-54321"
@@ -59,7 +63,9 @@ resourceLogs:
5963
intValue: "1234"
6064
body: {}
6165
eventName: db.server.query_sample
62-
timeUnixNano: "1754284840912240000"
66+
spanId: "2222222222222222"
67+
timeUnixNano: "1774540151557334000"
68+
traceId: "11111111111111111111111111111111"
6369
scope:
6470
name: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/mysqlreceiver
6571
version: latest

receiver/mysqlreceiver/testdata/scraper/expectedTopQueries.yaml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
resourceLogs:
2-
- resource: {}
2+
- resource:
3+
attributes:
4+
- key: mysql.instance.endpoint
5+
value:
6+
stringValue: localhost:3306
37
scopeLogs:
48
- logRecords:
59
- attributes:

0 commit comments

Comments
 (0)