mirror of
https://github.com/zoriya/drizzle-otel.git
synced 2025-12-06 00:46:09 +00:00
add changeset, update README
This commit is contained in:
@@ -4,6 +4,10 @@ OpenTelemetry instrumentation for the [Resend](https://resend.com) Node.js SDK.
|
||||
Capture spans for every Resend API call, enrich them with operation metadata,
|
||||
and keep an eye on message delivery from your traces.
|
||||
|
||||

|
||||
|
||||
_Visualize your email operations with detailed span information including recipients, subject lines, and delivery status._
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
@@ -30,7 +34,7 @@ await resend.emails.send({
|
||||
});
|
||||
```
|
||||
|
||||
`instrumentResend` wraps the instance you already use—no configuration changes
|
||||
`instrumentResend` wraps the instance you already use — no configuration changes
|
||||
needed. Every SDK call creates a client span with useful attributes.
|
||||
|
||||
## What Gets Traced
|
||||
@@ -41,36 +45,24 @@ This instrumentation specifically wraps the `resend.emails.send` method (and its
|
||||
|
||||
Each span includes:
|
||||
|
||||
| Attribute | Description | Example |
|
||||
| --- | --- | --- |
|
||||
| `messaging.system` | Constant value `resend` | `resend` |
|
||||
| `messaging.operation` | Operation type | `send` |
|
||||
| `resend.resource` | Resource name | `emails` |
|
||||
| `resend.target` | Full operation target | `emails.send` |
|
||||
| `resend.to_addresses` | Comma-separated TO addresses | `user@example.com, another@example.com` |
|
||||
| `resend.cc_addresses` | Comma-separated CC addresses (if present) | `cc@example.com` |
|
||||
| `resend.bcc_addresses` | Comma-separated BCC addresses (if present) | `bcc@example.com` |
|
||||
| `resend.recipient_count` | Total number of recipients | `3` |
|
||||
| `resend.from` | Sender email address | `noreply@example.com` |
|
||||
| `resend.subject` | Email subject | `Welcome to our service` |
|
||||
| `resend.template_id` | Template ID (if using templates) | `tmpl_123` |
|
||||
| `resend.message_id` | Message ID returned by Resend | `email_123` |
|
||||
| `resend.message_count` | Number of messages sent (always 1 for single sends) | `1` |
|
||||
| Attribute | Description | Example |
|
||||
| ------------------------ | --------------------------------------------------- | --------------------------------------- |
|
||||
| `messaging.system` | Constant value `resend` | `resend` |
|
||||
| `messaging.operation` | Operation type | `send` |
|
||||
| `resend.resource` | Resource name | `emails` |
|
||||
| `resend.target` | Full operation target | `emails.send` |
|
||||
| `resend.to_addresses` | Comma-separated TO addresses | `user@example.com, another@example.com` |
|
||||
| `resend.cc_addresses` | Comma-separated CC addresses (if present) | `cc@example.com` |
|
||||
| `resend.bcc_addresses` | Comma-separated BCC addresses (if present) | `bcc@example.com` |
|
||||
| `resend.recipient_count` | Total number of recipients | `3` |
|
||||
| `resend.from` | Sender email address | `noreply@example.com` |
|
||||
| `resend.subject` | Email subject | `Welcome to our service` |
|
||||
| `resend.template_id` | Template ID (if using templates) | `tmpl_123` |
|
||||
| `resend.message_id` | Message ID returned by Resend | `email_123` |
|
||||
| `resend.message_count` | Number of messages sent (always 1 for single sends) | `1` |
|
||||
|
||||
The instrumentation captures email addresses and metadata to help with debugging and monitoring, while avoiding sensitive email content.
|
||||
|
||||
## Configuration
|
||||
|
||||
```ts
|
||||
instrumentResend(resend, {
|
||||
tracerName: "my-service",
|
||||
tracer: myCustomTracer, // optional: bring your own tracer
|
||||
});
|
||||
```
|
||||
|
||||
- `tracerName`: Custom name for the tracer (defaults to `@kubiks/otel-resend`)
|
||||
- `tracer`: Use an existing tracer instance instead of creating a new one
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
@@ -4,7 +4,6 @@ import {
|
||||
SpanStatusCode,
|
||||
trace,
|
||||
type Span,
|
||||
type Tracer,
|
||||
} from "@opentelemetry/api";
|
||||
import type { Resend, CreateEmailOptions, CreateEmailResponse } from "resend";
|
||||
|
||||
@@ -30,11 +29,6 @@ export const SEMATTRS_RESEND_BCC_ADDRESSES = "resend.bcc_addresses" as const;
|
||||
export const SEMATTRS_RESEND_FROM = "resend.from" as const;
|
||||
export const SEMATTRS_RESEND_SUBJECT = "resend.subject" as const;
|
||||
|
||||
export interface InstrumentResendConfig {
|
||||
tracerName?: string;
|
||||
tracer?: Tracer;
|
||||
}
|
||||
|
||||
interface InstrumentedResend extends Resend {
|
||||
[INSTRUMENTED_FLAG]?: true;
|
||||
}
|
||||
@@ -130,17 +124,13 @@ function finalizeSpan(span: Span, error?: unknown): void {
|
||||
span.end();
|
||||
}
|
||||
|
||||
export function instrumentResend(
|
||||
client: Resend,
|
||||
config?: InstrumentResendConfig,
|
||||
): Resend {
|
||||
export function instrumentResend(client: Resend): Resend {
|
||||
// Check if already instrumented
|
||||
if ((client as InstrumentedResend)[INSTRUMENTED_FLAG]) {
|
||||
return client;
|
||||
}
|
||||
|
||||
const tracerName = config?.tracerName ?? DEFAULT_TRACER_NAME;
|
||||
const tracer = config?.tracer ?? trace.getTracer(tracerName);
|
||||
const tracer = trace.getTracer(DEFAULT_TRACER_NAME);
|
||||
|
||||
const originalSend = client.emails.send.bind(client.emails);
|
||||
const originalCreate = client.emails.create
|
||||
|
||||
Reference in New Issue
Block a user