Skip to content
Merged
42 changes: 35 additions & 7 deletions develop-docs/sdk/telemetry/logs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@
title: Logs
description: Structured logging protocol with severity levels, trace context, and batched envelope delivery.
spec_id: sdk/telemetry/logs
spec_version: 1.15.0
spec_version: 1.16.0
spec_status: stable
spec_depends_on:
- id: sdk/foundations/transport/envelopes
version: ">=1.0.0"
- id: sdk/foundations/state-management/scopes/attributes
version: ">=1.0.0"
spec_changelog:
- version: 1.16.0
date: 2026-03-04
summary: Add sentry.timestamp.sequence attribute for deterministic log ordering
- version: 1.15.0
date: 2026-02-03
summary: Clarified 100 logs per envelope hard limit, SDKs MAY use lower buffer limit
Expand Down Expand Up @@ -290,6 +293,25 @@ Logs **SHOULD** be associated with replays. If a log is recorded during an activ

</SpecSection>

### Log Ordering

<SpecSection id="log-ordering" status="candidate" since="1.16.0">

Some runtimes (notably Cloudflare Workers) freeze timer APIs (`Date.now()`, `performance.now()`) during synchronous execution, causing multiple logs to share identical timestamps. SDKs that target runtimes where timestamps may be frozen or lack sub-millisecond precision **MUST** attach a `sentry.timestamp.sequence` integer attribute to every log. SDKs that only target runtimes with reliable sub-millisecond timestamps **MAY** omit it.

When sent, the sequence integer **MUST**:
- Start at `0` when the SDK initializes.
- Increment by `1` for each log that is captured.
- Reset to `0` when:
- The SDK is re-initialized.
- The current log's integer millisecond differs from the previous log's integer millisecond (i.e., `floor(timestamp_seconds * 1000)` changes).

The sequence provides deterministic ordering within a single SDK instance. It does not guarantee ordering across independent processes or workers, which have separate counters. The reset behavior ensures the sequence only increments for consecutive logs that share the same timestamp.

</SpecSection>

### Debug Mode

<SpecSection id="debug-mode" status="candidate" since="1.0.0">

### Debug Mode
Expand Down Expand Up @@ -563,7 +585,8 @@ A complete `log` envelope with six log entries at different severity levels:
},
"sentry.message.parameter.0": { "value": 120, "type": "integer" },
"sentry.message.parameter.1": { "value": 85, "type": "integer" },
"sentry.message.parameter.2": { "value": 60, "type": "integer" }
"sentry.message.parameter.2": { "value": 60, "type": "integer" },
"sentry.timestamp.sequence": { "value": 0, "type": "integer" }
}
},
{
Expand All @@ -588,7 +611,8 @@ A complete `log` envelope with six log entries at different severity levels:
"value": "ProductCard",
"type": "string"
},
"sentry.message.parameter.1": { "value": 3, "type": "integer" }
"sentry.message.parameter.1": { "value": 3, "type": "integer" },
"sentry.timestamp.sequence": { "value": 1, "type": "integer" }
}
},
{
Expand All @@ -613,7 +637,8 @@ A complete `log` envelope with six log entries at different severity levels:
"value": "checkout_form",
"type": "string"
},
"sentry.message.parameter.1": { "value": 8, "type": "integer" }
"sentry.message.parameter.1": { "value": 8, "type": "integer" },
"sentry.timestamp.sequence": { "value": 2, "type": "integer" }
}
},
{
Expand All @@ -639,7 +664,8 @@ A complete `log` envelope with six log entries at different severity levels:
"type": "string"
},
"sentry.message.parameter.1": { "value": 2500, "type": "integer" },
"sentry.message.parameter.2": { "value": 1000, "type": "integer" }
"sentry.message.parameter.2": { "value": 1000, "type": "integer" },
"sentry.timestamp.sequence": { "value": 3, "type": "integer" }
}
},
{
Expand All @@ -666,7 +692,8 @@ A complete `log` envelope with six log entries at different severity levels:
"sentry.message.parameter.0": {
"value": "prod_123, prod_456",
"type": "string"
}
},
"sentry.timestamp.sequence": { "value": 4, "type": "integer" }
}
},
{
Expand Down Expand Up @@ -695,7 +722,8 @@ A complete `log` envelope with six log entries at different severity levels:
"sentry.message.parameter.1": {
"value": "UPDATE_CART",
"type": "string"
}
},
"sentry.timestamp.sequence": { "value": 5, "type": "integer" }
}
}
]
Expand Down
39 changes: 33 additions & 6 deletions develop-docs/sdk/telemetry/metrics.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@
title: Metrics
description: Counter, gauge, and distribution metrics sent as batched trace_metric envelope items.
spec_id: sdk/telemetry/metrics
spec_version: 2.5.0
spec_version: 2.6.0
spec_status: stable
spec_depends_on:
- id: sdk/foundations/transport/envelopes
version: ">=1.0.0"
- id: sdk/foundations/state-management/scopes/attributes
version: ">=1.0.0"
spec_changelog:
- version: 2.6.0
date: 2026-03-04
summary: Add sentry.timestamp.sequence attribute for deterministic metric ordering
- version: 2.5.0
date: 2026-02-12
summary: Clarified sendDefaultPii gating for user attributes — allowed when user manually sets data
Expand Down Expand Up @@ -187,6 +190,25 @@ Whenever possible, metrics **SHOULD** be linked to replays. If a metric is recor

</SpecSection>

### Metric Ordering

<SpecSection id="metric-ordering" status="candidate" since="2.6.0">

Some runtimes (notably Cloudflare Workers) freeze timer APIs (`Date.now()`, `performance.now()`) during synchronous execution, causing multiple metrics to share identical timestamps. SDKs that target runtimes where timestamps may be frozen or lack sub-millisecond precision **MUST** attach a `sentry.timestamp.sequence` integer attribute to every metric. SDKs that only target runtimes with reliable sub-millisecond timestamps **MAY** omit it.

When sent, the sequence integer **MUST**:
- Start at `0` when the SDK initializes.
- Increment by `1` for each metric that is captured.
- Reset to `0` when:
- The SDK is re-initialized.
- The current metric's integer millisecond differs from the previous metric's integer millisecond (i.e., `floor(timestamp_seconds * 1000)` changes).

The sequence provides deterministic ordering within a single SDK instance. It does not guarantee ordering across independent processes or workers, which have separate counters. The reset behavior ensures the sequence only increments for consecutive metrics that share the same timestamp.

</SpecSection>

### Data Category and Rate Limiting

<SpecSection id="data-category-rate-limiting" status="stable" since="2.0.0">

### Data Category and Rate Limiting
Expand Down Expand Up @@ -547,7 +569,8 @@ SentrySDK.metrics()
"sentry.sdk.name": { "value": "sentry.javascript.browser", "type": "string" },
"sentry.sdk.version": { "value": "10.17.0", "type": "string" },
"sentry.environment": { "value": "production", "type": "string" },
"sentry.release": { "value": "1.0.0", "type": "string" }
"sentry.release": { "value": "1.0.0", "type": "string" },
"sentry.timestamp.sequence": { "value": 0, "type": "integer" }
}
},
{
Expand All @@ -562,7 +585,8 @@ SentrySDK.metrics()
"endpoint": { "value": "/api/users", "type": "string" },
"method": { "value": "POST", "type": "string" },
"sentry.sdk.name": { "value": "sentry.javascript.browser", "type": "string" },
"sentry.sdk.version": { "value": "10.17.0", "type": "string" }
"sentry.sdk.version": { "value": "10.17.0", "type": "string" },
"sentry.timestamp.sequence": { "value": 1, "type": "integer" }
Comment on lines 585 to +589
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

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

In this full envelope example, the first metric item includes sentry.environment and sentry.release, but this item omits them even though they’re listed as default attributes (when defined) and would normally be consistent across metrics from the same SDK instance. Consider adding them here too, or removing them from the earlier item, so the example matches the spec rules.

Copilot uses AI. Check for mistakes.
}
},
{
Expand All @@ -577,7 +601,8 @@ SentrySDK.metrics()
"cache_name": { "value": "user_sessions", "type": "string" },
"region": { "value": "us-west-1", "type": "string" },
"sentry.sdk.name": { "value": "sentry.javascript.browser", "type": "string" },
"sentry.sdk.version": { "value": "10.17.0", "type": "string" }
"sentry.sdk.version": { "value": "10.17.0", "type": "string" },
"sentry.timestamp.sequence": { "value": 0, "type": "integer" }
}
},
{
Expand All @@ -593,7 +618,8 @@ SentrySDK.metrics()
"table": { "value": "users", "type": "string" },
"sentry.sdk.name": { "value": "sentry.javascript.browser", "type": "string" },
"sentry.sdk.version": { "value": "10.17.0", "type": "string" },
"sentry.origin": { "value": "auto.db.graphql", "type": "string" }
"sentry.origin": { "value": "auto.db.graphql", "type": "string" },
"sentry.timestamp.sequence": { "value": 1, "type": "integer" }
}
},
{
Expand All @@ -607,7 +633,8 @@ SentrySDK.metrics()
"cohort": { "value": "beta", "type": "string" },
"sentry.sdk.name": { "value": "sentry.javascript.browser", "type": "string" },
"sentry.sdk.version": { "value": "10.17.0", "type": "string" },
"sentry.replay_id": { "value": "36b75d9fa11f45459412a96c41bdf691", "type": "string" }
"sentry.replay_id": { "value": "36b75d9fa11f45459412a96c41bdf691", "type": "string" },
"sentry.timestamp.sequence": { "value": 0, "type": "integer" }
}
}
]
Expand Down
Loading