{"id":15137808,"url":"https://github.com/serilog/serilog-sinks-opentelemetry","last_synced_at":"2025-10-23T13:30:50.830Z","repository":{"id":63426459,"uuid":"558227649","full_name":"serilog/serilog-sinks-opentelemetry","owner":"serilog","description":"Serilog to OpenTelemetry Logs sink","archived":false,"fork":false,"pushed_at":"2024-05-08T23:08:35.000Z","size":329,"stargazers_count":100,"open_issues_count":10,"forks_count":17,"subscribers_count":15,"default_branch":"dev","last_synced_at":"2024-05-16T07:17:55.158Z","etag":null,"topics":["open-telemetry","serilog"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/serilog.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-10-27T06:10:55.000Z","updated_at":"2024-06-06T10:30:48.214Z","dependencies_parsed_at":"2024-06-06T10:30:47.463Z","dependency_job_id":"556680c0-c8d3-4b71-9d24-89de8e4053e9","html_url":"https://github.com/serilog/serilog-sinks-opentelemetry","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/serilog%2Fserilog-sinks-opentelemetry","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/serilog%2Fserilog-sinks-opentelemetry/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/serilog%2Fserilog-sinks-opentelemetry/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/serilog%2Fserilog-sinks-opentelemetry/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/serilog","download_url":"https://codeload.github.com/serilog/serilog-sinks-opentelemetry/tar.gz/refs/heads/dev","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":237834599,"owners_count":19373757,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["open-telemetry","serilog"],"created_at":"2024-09-26T07:02:11.030Z","updated_at":"2025-10-23T13:30:50.824Z","avatar_url":"https://github.com/serilog.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Serilog.Sinks.OpenTelemetry\u0026nbsp;[![Build status](https://github.com/serilog/serilog-sinks-opentelemetry/actions/workflows/ci.yml/badge.svg?branch=dev)](https://github.com/serilog/serilog-sinks-opentelemetry/actions)\u0026nbsp;[![NuGet Version](https://img.shields.io/nuget/vpre/Serilog.Sinks.OpenTelemetry.svg?style=flat)](https://www.nuget.org/packages/Serilog.Sinks.OpenTelemetry/)\n\nThis Serilog sink transforms Serilog events into OpenTelemetry\n`LogRecord`s and sends them to an OTLP (gRPC or HTTP) endpoint.\n\nThe sink aims for full compliance with the OpenTelemetry Logs protocol. It\ndoes not depend on the OpenTelemetry SDK or .NET API.\n\nOpenTelemetry supports attributes with scalar values, arrays, and maps.\nSerilog does as well. Consequently, the sink does a one-to-one\nmapping between Serilog properties and OpenTelemetry attributes.\nThere is no flattening, renaming, or other modifications done to the\nproperties by default.\n\n## Getting started\n\nTo use the OpenTelemetry sink, first install the\n[NuGet package](https://nuget.org/packages/serilog.sinks.opentelemetry):\n\n```shell\ndotnet add package Serilog.Sinks.OpenTelemetry\n```\n\nThen enable the sink using `WriteTo.OpenTelemetry()`:\n\n```csharp\nLog.Logger = new LoggerConfiguration()\n    .WriteTo.OpenTelemetry()\n    .CreateLogger();\n```\n\nGenerate logs using the `Log.Information(...)` and similar methods to\nsend transformed logs to a local OpenTelemetry OTLP endpoint.\n\nA more complete configuration would specify `Endpoint`, `Protocol`,\nand other parameters, such as`ResourceAttributes`, as shown in the\nexamples below.\n\n## Configuration\n\nThis sink supports two configuration styles: inline and options.\nInline configuration is appropriate for simple, local logging\nsetups, and looks like:\n\n```csharp\nLog.Logger = new LoggerConfiguration()\n    .WriteTo.OpenTelemetry(\n        endpoint: \"http://127.0.0.1:4318\",\n        protocol: OtlpProtocol.HttpProtobuf)\n    .CreateLogger();\n```\n\nMore complicated use cases need to use options-style\nconfiguration, which looks like:\n\n```csharp\nLog.Logger = new LoggerConfiguration()\n    .WriteTo.OpenTelemetry(options =\u003e\n    {\n        options.Endpoint = \"http://127.0.0.1:4318\";\n        options.Protocol = OtlpProtocol.HttpProtobuf;\n    })\n    .CreateLogger();\n```\n\nThis supports the sink's full set of configuration options. See the\n`OpenTelemetrySinkOptions.cs` file for the full set of options. \nSome of the more important parameters are discussed in the following\nsections.\n\n### Endpoint and protocol\n\nThe default endpoint and protocol are `http://localhost:4317` and `OtlpProtocol.Grpc`.\n\nIn most production scenarios, you'll need to set an endpoint and protocol to suit your\ndeployment environment. To do so, add the `endpoint` argument to the `WriteTo.OpenTelemetry()` call.\n\nYou may also want to set the protocol. The supported values\nare:\n\n- `OtlpProtocol.Grpc`: Sends a protobuf representation of the \n   OpenTelemetry Logs over a gRPC connection (the default).\n- `OtlpProtocol.HttpProtobuf`: Sends a protobuf representation of the\n   OpenTelemetry Logs over an HTTP connection.\n\n### Resource attributes\n\nOpenTelemetry logs may contain a \"resource\" that provides metadata concerning\nthe entity associated with the logs, typically a service or library. These\nmay contain \"resource attributes\" and are emitted for all logs flowing through\nthe configured logger.\n\nThese resource attributes may be provided as a `Dictionary\u003cstring, Object\u003e`\nwhen configuring a logger. OpenTelemetry allows resource attributes\nwith rich values; however, this implementation _only_ supports resource \nattributes with primitive values. \n\n\u003e :warning: Resource attributes with non-primitive values will be\n\u003e silently ignored.\n\nThis example shows how the resource attributes can be specified when\nthe logger is configured.\n\n```csharp\nLog.Logger = new LoggerConfiguration()\n    .WriteTo.OpenTelemetry(options =\u003e\n    {\n        options.Endpoint = \"http://127.0.0.1:4317\";\n        options.ResourceAttributes = new Dictionary\u003cstring, object\u003e\n        {\n            [\"service.name\"] = \"test-logging-service\",\n            [\"index\"] = 10,\n            [\"flag\"] = true,\n            [\"value\"] = 3.14\n        };\n    })\n    .CreateLogger();\n```\n\n### Environment variable overrides\n\nThe sink also recognizes a selection of the `OTEL_OTLP_EXPORTER_*` environment variables described in\nthe [OpenTelemetry documentation](https://opentelemetry.io/docs/specs/otel/protocol/exporter/), and will\noverride programmatic configuration with any environment variable values present at runtime.\n\nTo switch off this behavior, pass `ignoreEnvironment: true` to the `WriteTo.OpenTelemetry()` configuration\nmethods.\n\n## Serilog `LogEvent` to OpenTelemetry log record mapping\n\nThe following table provides the mapping between the Serilog log \nevents and the OpenTelemetry log records. \n\nSerilog `LogEvent`               | OpenTelemetry `LogRecord`                  | Comments                                                                                      |\n---------------------------------|--------------------------------------------|-----------------------------------------------------------------------------------------------| \n`Exception.GetType().ToString()` | `Attributes[\"exception.type\"]`             |                                                                                               |\n`Exception.Message`              | `Attributes[\"exception.message\"]`          | Ignored if empty                                                                              |\n`Exception.StackTrace`           | `Attributes[\"exception.stacktrace\"]`       | Value of `ex.ToString()`                                                                      |\n`Level`                          | `SeverityNumber`                           | Serilog levels are mapped to corresponding OpenTelemetry severities                           | \n`Level.ToString()`               | `SeverityText`                             |                                                                                               |\n`Message`                        | `Body`                                     | Culture-specific formatting can be provided via sink configuration                            |\n`MessageTemplate`                | `Attributes[\"message_template.text\"]`      | Requires `IncludedData. MessageTemplateText` (enabled by default)                             |\n`MessageTemplate` (MD5)          | `Attributes[\"message_template.hash.md5\"]`  | Requires `IncludedData. MessageTemplateMD5 HashAttribute`                                     |\n`Properties`                     | `Attributes`                               | Each property is mapped to an attribute keeping the name; the value's structure is maintained |\n`SpanId` (`Activity.Current`)    | `SpanId`                                   | Requires `IncludedData.SpanIdField` (enabled by default)                                           |\n`Timestamp`                      | `TimeUnixNano`                             | .NET provides 100-nanosecond precision                                                        |\n`TraceId` (`Activity.Current`)   | `TraceId`                                  | Requires `IncludedData.TraceIdField` (enabled by default)                                          |\n\n### Configuring included data\n\nThis sink supports configuration of how common OpenTelemetry fields are populated from\nthe Serilog `LogEvent` and .NET `Activity` context via the `IncludedData` flags enum:\n\n```csharp\nLog.Logger = new LoggerConfiguration()\n    .WriteTo.OpenTelemetry(options =\u003e\n    {\n        options.Endpoint = \"http://127.0.0.1:4317\";\n        options.IncludedData = IncludedData.MessageTemplateTextAttribute |\n                              IncludedData.SpecRequiredResourceAttributes;\n    })\n    .CreateLogger();\n```\n\nThe example shows the default value; `IncludedData.MessageTemplateMD5HashAttribute` can\nalso be used to add the MD5 hash of the message template.\n\n## Sending traces through the sink\n\nSerilog `LogEvents` that carry a `SpanStartTimestamp` property of type `DateTime` will be\nrecognized as spans by this sink, and sent using the appropriate OpenTelemetry endpoint\nand schema. The properties recognized by the sink match the ones emitted by\n[SerilogTracing](https://github.com/serilog-tracing/serilog-tracing).\n\nIn addition to the field mapping performed for log records, events that represent trace\nspans can carry the special properties listed below.\n\nSerilog `LogEvent`               | OpenTelemetry `Span` | Comments                               |\n---------------------------------|----------------------|----------------------------------------| \n`MessageTemplate`                | `Name`               |                                        |\n`Properties[\"ParentSpanId\"]` | `ParentSpanId`       | Value must be of type `ActivitySpanId` |\n`Properties[\"SpanKind\"]` | `Kind`               | Value must be of type `ActivityKind`   |\n`Properties[\"SpanStartTimestamp\"]` | `StartTimeUnixNano`  | Value must be of type `DateTime`; .NET provides 100-nanosecond precision     |\n`Timestamp`                | `EndTimeUnixNano`    | .NET provides 100-nanosecond precision |\n\n## Suppressing other instrumentation\n\nIf the sink is used in an application that also instruments HTTP or gRPC requests using the OpenTelemetry libraries,\nthis can be suppressed for outbound requests made by the sink using `OnBeginSuppressInstrumentation`:\n\n```csharp\nLog.Logger = new LoggerConfiguration()\n    .WriteTo.OpenTelemetry(options =\u003e\n    {\n        options.OnBeginSuppressInstrumentation =\n            OpenTelemetry.SuppressInstrumentationScope.Begin;\n        // ...\n```\n\n## Example\n\nThe `example/Example` subdirectory contains an example application that logs\nto a local [OpenTelemetry collector](https://opentelemetry.io/docs/collector/).\nSee the README in that directory for instructions on how to run the example.\n\n## .NET Framework Activity Traces\n\nIn .NET 5 and later versions, the `Activity.DefaultIdFormat` is `ActivityIdFormat.W3C`. In previous versions, the default format is `ActivityIdFormat.Hierarchical`.\nTo make use of the **Activity**'s traces and spans, you should set the global `Activity.DefaultIdFormat` to `ActivityIdFormat.W3C` in .NET Framework environments.\nRead more: [Default ActivityIdFormat is W3C](https://learn.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/5.0/default-activityidformat-changed)\n\n_Copyright \u0026copy; Serilog Contributors - Provided under the [Apache License, Version 2.0](http://apache.org/licenses/LICENSE-2.0.html)._\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fserilog%2Fserilog-sinks-opentelemetry","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fserilog%2Fserilog-sinks-opentelemetry","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fserilog%2Fserilog-sinks-opentelemetry/lists"}