Skip to content

Add service.name/version to OTLP log resource#5536

Open
ramonsmits wants to merge 1 commit into
authfrom
otel-service-names
Open

Add service.name/version to OTLP log resource#5536
ramonsmits wants to merge 1 commit into
authfrom
otel-service-names

Conversation

@ramonsmits

@ramonsmits ramonsmits commented Jun 15, 2026

Copy link
Copy Markdown
Member

Summary

The OTLP log exporter was registered with a bare AddOtlpExporter() and no
OpenTelemetry resource, so exported logs arrived as unknown_service and couldn't be
attributed or correlated. This PR gives every exported log record a service identity for
all three instances (ServiceControl, Audit, Monitoring), matching the service.name
already used by the Audit metrics resource so logs and metrics correlate.

What changed

LoggerUtil.Initialize(serviceName, serviceVersion) is called once at startup (in each
Program.cs, before any logger is created) and builds a single OpenTelemetry resource
shared by both the host logging pipeline and the static bootstrap loggers — so all
exported records are attributed, including early startup diagnostics.

Attribute Value
service.name instance name (same as the metrics resource)
service.version instance version
service.instance.id auto-generated per process start

Operator configuration

Enable OTLP logging by adding Otlp to LoggingProviders; the endpoint comes from the
standard OTEL_EXPORTER_OTLP_ENDPOINT. The resource uses ResourceBuilder.CreateDefault(),
so operators can tag a deployment via OTEL_RESOURCE_ATTRIBUTES (these ride on every record):

OTEL_RESOURCE_ATTRIBUTES=deployment.environment=production,service.namespace=orders,acme.region=eu-west-1

Code-set service.* win; extra attributes are merged in. For a stable id across restarts,
set service.instance.id explicitly here.

Testing

# collector.yaml
receivers: { otlp: { protocols: { grpc: { endpoint: 0.0.0.0:4317 } } } }
exporters: { debug: { verbosity: detailed } }
service: { pipelines: { logs: { receivers: [otlp], exporters: [debug] } } }
podman run --rm -p 4317:4317 -v $PWD/collector.yaml:/etc/otelcol/config.yaml:z otel/opentelemetry-collector
# then start any instance with:  LoggingProviders=NLog,Otlp  OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317

The collector prints each record's Resource attributes with service.name = <instance name>.

@ramonsmits ramonsmits changed the title ✨ Add service.name/version to OTLP log resource Add service.name/version to OTLP log resource Jun 15, 2026
@ramonsmits ramonsmits force-pushed the otel-service-names branch from a61e0b6 to 560fba3 Compare June 15, 2026 15:15
The OTLP log exporter was registered with a bare AddOtlpExporter() and no
OpenTelemetry resource, so exported log records had no service identity and
showed up as "unknown_service" in the backend.

LoggerUtil.Initialize(serviceName, serviceVersion) is now called once at process
startup (in each instance's Program.cs, before any logger is created) and builds a
single OpenTelemetry resource — service.name = instance name, service.version =
instance version, plus an auto-generated service.instance.id. Both the host logging
pipeline and the static bootstrap loggers (CreateStaticLogger) share that resource,
so every exported record — including early startup diagnostics — is attributed to
the instance. service.name matches the value used by the Audit metrics resource, so
logs and metrics correlate.

The resource still uses ResourceBuilder.CreateDefault(), so operators can enrich it
with deployment attributes via OTEL_SERVICE_NAME / OTEL_RESOURCE_ATTRIBUTES.
@ramonsmits ramonsmits force-pushed the otel-service-names branch from 560fba3 to 76bdd61 Compare June 17, 2026 20:00
// Establish the telemetry identity once, before any logger is created, so every logger — including the
// static bootstrap loggers — attributes exported OTLP logs to this instance. Mirrors the InstanceName
// resolution in Settings (InternalQueueName is the legacy fallback for the instance name).
var instanceName = SettingsReader.Read(Settings.SettingsRootNamespace, "InstanceName",

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@WilliamBZA @dvdstelt this is really needed to ensure OTel related attributes are set.

The version could be extracted in the LoggerUtil.Initialize as that version is the same for all SC assemblies in the build.

However, the name is not, unfortnately although very similar for all 3 instances SettingsReader can be used in LoggerUtil but not Settings which is instance specific.

Any refactorings you can think of to maybe this a bit less fugly?

@ramonsmits ramonsmits marked this pull request as ready for review June 17, 2026 20:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant