Demonstration of different approaches to dotnet logs when using OpenTelemetry and Serilog.
There are three services in the the docker-compose.yml file
Service | Purpose | Local Url | More Info |
---|---|---|---|
seq | Logging backend that recieves logs and allows advanced searching | http://localhost:5002 | Seq product |
otel-collector | Collector for OpenTelemetry which receives traces/metrics/logs and writes to the console, as well as optionally to Honeycomb | N/A | Otel Collector docs |
webhost | Simple API for testing OTel logging approaches | http://localhost:5001/swagger/index.html | See the source code |
If you want to send trace telemetry to Honeycomb you need to modify the otel-collector-config.yaml file by updating the "x-honeycomb-team
and x-honeycomb-dataset
values with your own information. You also need to adjust the service pipeline configuration to ensure that the otlp
exporter is present for the traces pipeline.
Open a terminal in the repo root and run
docker compose up
The console will print output, mostly from the otel-collector service with the raw OTel data for traces, metrics and logs.
To generate trace and log data do the following:
- Open the webhost swagger UI
- Expand the
GET /carts/{id}/
method - Click the
Try it out
button - Enter a value for
id
between 1 and 10 inclusive - Click the
Execute
button
Repeat the above a number of times with different values for the cart Id, ensuring you have a spread of values below and above cart Id = 5.
As the requests are processed, telemetry data is sent to the OTel collector which batch processes it and then flushes to the console and optionally to Honeycomb too (if configured).
There are two alternative approaches explored here:
- Augmenting the current trace span to include log information in the span events array
- This is achieved via a custom Serilog sink which adds logs to the current span by way of
Activity.Current.AddEvent(...)
- In this approach logs are transformed into information attached to telemetry traces and sent to the OTel collector via the traces gRPC method
- This is achieved via a custom Serilog sink which adds logs to the current span by way of
- Using the OpenTelemetry logs signal directly
- In this approach logs are converted to OTLP log format and sent to the OTel Collector via the logs gRPC method
- Note that since the OTel logs signal type is not fully stable this approach is currently considered experimental
Suppose our goal is to find all log records where the number of items in the cart is greater than 5.
- Open the Seq dashboard
- In the search bar enter
Cart.ItemsCount > 5
- Click the Go button
- All logs are displayed
- Easy!
- Open the Honeycomb dashboard
- Select
New Query
- Select the correct dataset where the trace data was sent
- Click
Run Query
to see recent Raw Data - Observe that there is a field called
Cart
with content of the form{ CartId: 9, ItemsCount: 9 }
- This data was sent to Honeycomb as a span event attribute with the format
Cart: STRING({ CartId: 9, ItemsCount: 9 })
so Honeycomb records the field as string content - There is no immediate way to ad-hoc query the contents of this field
- There is a setting at the Honeycomb dataset level to automatically unpack JSON objects but this doesn't appear to apply here
- It is possible to use Derived Columns to extract this information, however that requires setup of a new derived column for each JSON property that you want to query on