Skip to content

Commit 1cae8bf

Browse files
committed
Align better with OTEL messaging conventions
We were not tracking the user (client) id anywhere, which would make it very hard to correlate and track issues per user. Updated based on the latest stable conventions, the new (fully documented) metrics and span attributes. See https://opentelemetry.io/docs/specs/semconv/messaging/messaging-spans/#consumer-spans NOTE: this is a BREAKING change from previous telemetry.
1 parent cb24e3e commit 1cae8bf

File tree

3 files changed

+30
-7
lines changed

3 files changed

+30
-7
lines changed

readme.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,28 @@ this repository:
404404

405405
![](https://raw.githubusercontent.com/devlooped/WhatsApp/main/assets/img/aspire.png)
406406

407+
The spans/activites created by the `OpenTelemetryHandler` follow the [OpenTelemetry Semantic Conventions for Messaging Spans](https://opentelemetry.io/docs/specs/semconv/messaging/messaging-spans/).
408+
Specifically, it uses a [consumer span](https://opentelemetry.io/docs/specs/semconv/messaging/messaging-spans/#consumer-spans)
409+
named "process whatsapp" to track the processing of incoming WhatsApp messages.
410+
411+
| Attribute/Tag | Value | Description | OTEL Convention |
412+
|-----------|-------|-------------|-----------------|
413+
| `messaging.system` | `whatsapp` | Identifies the messaging system being used. | [messaging.system](https://opentelemetry.io/docs/specs/semconv/registry/attributes/messaging/) |
414+
| `messaging.operation.name` | `process` | The name of the operation performed on the message, indicating processing of incoming messages. | [messaging.operation.name](https://opentelemetry.io/docs/specs/semconv/registry/attributes/messaging/) |
415+
| `messaging.destination.name` | Service ID (e.g., WhatsApp Business Account phone number) | The name of the destination to which the message is sent. In this context, it's the service identifier for the WhatsApp endpoint. | [messaging.destination.name](https://opentelemetry.io/docs/specs/semconv/registry/attributes/messaging/) |
416+
| `messaging.client.id` | User phone number | The identifier of the client that sent the message. | [messaging.client.id](https://opentelemetry.io/docs/specs/semconv/registry/attributes/messaging/) |
417+
| `messaging.message.id` | Message ID | The unique identifier of the message being processed. | [messaging.message.id](https://opentelemetry.io/docs/specs/semconv/registry/attributes/messaging/) |
418+
| `messaging.message.conversation_id` | Conversation ID (if available) | The identifier of the conversation the message belongs to, if applicable. | [messaging.message.conversation_id](https://opentelemetry.io/docs/specs/semconv/registry/attributes/messaging/) |
419+
420+
These attributes provide detailed context for tracing message processing flows in distributed systems.
421+
422+
In addition to spans, the handler emits metrics:
423+
- `messaging.process.duration` (histogram): Duration of WhatsApp message processing in seconds. See [OTEL convention](https://opentelemetry.io/docs/specs/semconv/messaging/messaging-metrics/#metric-messagingprocessduration)
424+
- `messaging.client.consumed.messages` (counter): Number of WhatsApp messages processed. See [OTEL convention](https://opentelemetry.io/docs/specs/semconv/messaging/messaging-metrics/#metric-messagingclientconsumedmessages)
425+
426+
These metrics also carry the same tags as the spans for correlation.
427+
428+
<!-- #content -->
407429

408430
## Scalability and Performance
409431

src/WhatsApp/OpenTelemetryExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ static class OpenTelemetryExtensions
2222
activity.AddTag("error.type", e.GetType().FullName);
2323
activity.SetStatus(ActivityStatusCode.Error, e.Message);
2424

25-
activity.AddEvent(new ActivityEvent("exception", tags: new(tags)));
25+
activity.AddEvent(new ActivityEvent("exception", tags: [.. tags]));
2626

2727
return tags;
2828
}

src/WhatsApp/OpenTelemetryHandler.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,14 +78,14 @@ public override IAsyncEnumerable<Response> HandleAsync(IEnumerable<IMessage> mes
7878
}
7979
else
8080
{
81-
using var span = activitySource.StartActivity("whatsapp process", ActivityKind.Consumer);
81+
using var span = activitySource.StartActivity("process whatsapp", ActivityKind.Consumer);
8282
if (span != null)
8383
{
8484
span.SetTag("messaging.system", "whatsapp");
85-
span.SetTag("messaging.destination", "whatsapp");
86-
span.SetTag("messaging.operation", "process");
85+
span.SetTag("messaging.operation.name", "process");
86+
span.SetTag("messaging.destination.name", message.ServiceId);
87+
span.SetTag("messaging.client.id", message.UserNumber);
8788
span.SetTag("messaging.message.id", message.Id);
88-
span.SetTag("messaging.client.id", message.ServiceId);
8989
if (message.ConversationId is string conversationId)
9090
span.SetTag("messaging.message.conversation_id", conversationId);
9191
}
@@ -94,8 +94,9 @@ public override IAsyncEnumerable<Response> HandleAsync(IEnumerable<IMessage> mes
9494
var tags = new TagList
9595
{
9696
{ "messaging.system", "whatsapp" },
97-
{ "messaging.operation", "process" },
98-
{ "messaging.client.id", message.ServiceId },
97+
{ "messaging.operation.name", "process" },
98+
{ "messaging.destination.name", message.ServiceId },
99+
{ "messaging.client.id", message.UserNumber },
99100
};
100101

101102
return base.HandleAsync(messages, cancellation).WithErrorHandlingAsync(

0 commit comments

Comments
 (0)