Skip to content

Commit

Permalink
[exporter/clickhouse] Fix incorrect ServiceName set for Logs Records (o…
Browse files Browse the repository at this point in the history
…pen-telemetry#36350)

#### Description
Fixing a bug in `clickhouseexporter` when ServiceName field in
ClickHouse for `otel_logs` table is set from previous Log Record, when
current LogRecord doesn't have `service.name` set

#### Link to tracking issue
Fixes open-telemetry#36349

#### Testing
Respective unit test is added to code

---------

Co-authored-by: Christos Markou <[email protected]>
Co-authored-by: Alex Boten <[email protected]>
  • Loading branch information
3 people authored and shivanthzen committed Dec 4, 2024
1 parent 7f167a2 commit 485117d
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 1 deletion.
27 changes: 27 additions & 0 deletions .chloggen/fix_clickhouse-exporter-log-service-name.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Use this changelog template to create an entry for release notes.

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

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

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Fix incorrect Resource Attribute `service.name` translation to ClickHouse ServiceName field for Logs Records

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

# (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:

# 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: []
2 changes: 1 addition & 1 deletion exporter/clickhouseexporter/exporter_logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,13 @@ func (e *logsExporter) pushLogsData(ctx context.Context, ld plog.Logs) error {
defer func() {
_ = statement.Close()
}()
var serviceName string

for i := 0; i < ld.ResourceLogs().Len(); i++ {
logs := ld.ResourceLogs().At(i)
res := logs.Resource()
resURL := logs.SchemaUrl()
resAttr := attributesToMap(res.Attributes())
var serviceName string
if v, ok := res.Attributes().Get(conventions.AttributeServiceName); ok {
serviceName = v.Str()
}
Expand Down
40 changes: 40 additions & 0 deletions exporter/clickhouseexporter/exporter_logs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,22 @@ func TestExporter_pushLogsData(t *testing.T) {
exporter := newTestLogsExporter(t, defaultEndpoint)
mustPushLogsData(t, exporter, simpleLogsWithNoTimestamp(1))
})
t.Run("test with 2 log records with different service.name", func(t *testing.T) {
initClickhouseTestServer(t, func(query string, values []driver.Value) error {
if strings.HasPrefix(query, "INSERT") {
body, _ := values[7].(string)
if body == "empty ServiceName" {
require.Equal(t, "", values[6])
} else {
require.Equal(t, "test-service", values[6])
}
}
return nil
})

exporter := newTestLogsExporter(t, defaultEndpoint)
mustPushLogsData(t, exporter, multipleLogsWithDifferentServiceName(1))
})
}

func TestLogsClusterConfig(t *testing.T) {
Expand Down Expand Up @@ -215,6 +231,30 @@ func simpleLogsWithNoTimestamp(count int) plog.Logs {
return logs
}

func multipleLogsWithDifferentServiceName(count int) plog.Logs {
logs := simpleLogs(count)
rl := logs.ResourceLogs().AppendEmpty()
rl.SetSchemaUrl("https://opentelemetry.io/schemas/1.4.0")
sl := rl.ScopeLogs().AppendEmpty()
sl.SetSchemaUrl("https://opentelemetry.io/schemas/1.7.0")
sl.Scope().SetName("io.opentelemetry.contrib.clickhouse")
sl.Scope().SetVersion("1.0.0")
sl.Scope().Attributes().PutStr("lib", "clickhouse")
timestamp := time.Unix(1703498029, 0)
for i := 0; i < count; i++ {
r := sl.LogRecords().AppendEmpty()
r.SetObservedTimestamp(pcommon.NewTimestampFromTime(timestamp))
r.SetSeverityNumber(plog.SeverityNumberError2)
r.SetSeverityText("error")
r.Body().SetStr("empty ServiceName")
r.Attributes().PutStr(conventions.AttributeServiceNamespace, "default")
r.SetFlags(plog.DefaultLogRecordFlags)
r.SetTraceID([16]byte{1, 2, 3, byte(i)})
r.SetSpanID([8]byte{1, 2, 3, byte(i)})
}
return logs
}

func mustPushLogsData(t *testing.T, exporter *logsExporter, ld plog.Logs) {
err := exporter.pushLogsData(context.TODO(), ld)
require.NoError(t, err)
Expand Down

0 comments on commit 485117d

Please sign in to comment.