From cc06312d91b85ecba46090d888da5a0153a7742a Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Tue, 4 Mar 2025 16:19:10 -0500 Subject: [PATCH 01/28] feat(logs): intial work on develop docs for sdk logging api --- .../sdk/data-model/envelope-items.mdx | 5 + develop-docs/sdk/telemetry/logs.mdx | 262 ++++++++++++++++++ 2 files changed, 267 insertions(+) create mode 100644 develop-docs/sdk/telemetry/logs.mdx diff --git a/develop-docs/sdk/data-model/envelope-items.mdx b/develop-docs/sdk/data-model/envelope-items.mdx index 31171a50a4fcb..32b7d041955c0 100644 --- a/develop-docs/sdk/data-model/envelope-items.mdx +++ b/develop-docs/sdk/data-model/envelope-items.mdx @@ -427,6 +427,11 @@ details. *None* +### Logs + +Item type `"logs"` contains a check-in payload encoded as JSON. + + ### Reserved Types Reserved types may not be written by any implementation. They are reserved for diff --git a/develop-docs/sdk/telemetry/logs.mdx b/develop-docs/sdk/telemetry/logs.mdx new file mode 100644 index 0000000000000..26f3be39f873d --- /dev/null +++ b/develop-docs/sdk/telemetry/logs.mdx @@ -0,0 +1,262 @@ +--- +title: Logs +sidebar_order: 3 +--- + + + +The Sentry Logs feature is under active development. The information in this document is subject to change. + + + +This document defines the format used by Sentry to ingest logs, as well as the SDK API and behavior that creates and sends logs to Sentry. + +## Logs Protocol + +Logs can be sent in two ways to Sentry, via the `logs` envelope and Sentry Log Schema, or the `otel_log` envelope and OpenTelemetry Log Schema. The `logs` envelope is the preferred way to send logs to Sentry, but the `otel_log` envelope is also supported. + +### `logs` Envelope + +### Log Severity Level + +The log severity level is a string that represents the severity of the log. The Sentry's default log severity level maps exactly to [OpenTelemetry's Severity text field](https://opentelemetry.io/docs/specs/otel/logs/data-model/#field-severitytext) on the OpenTelemetry Logs Spec.. + +- `trace` +- `debug` +- `info` +- `warn` +- `error` +- `fatal` + +Optionally the SDK can define a `log` log severity level, which maps to the `info` log severity level in Sentry. + +## Public API + +API wise the SDKs are required to expose logging methods which are to be defined in a `logger` module or namespace. The SDKs should also include some initialization options to configure the behavior of logs in the SDK. + +### Initialization Options + +The SDKs need to expose the following two configuration options: + +- `enableSentryLogs`/`enable_sentry_logs`: A boolean flag to control if log envelopes will be generated and sent to Sentry via the Sentry SDK's Logging APIs. If this flag is set to `false`, the SDK should not send logs to Sentry. Defaults to `false`. + +- `beforeSendLog`/`before_send_log`: A function that takes a log object and returns a log object. This function is called before sending the log to Sentry. It can be used to modify the log object or to prevent the log from being sent to Sentry. Defaults to `null`/`unset`. + +```js +Sentry.init({ + enableSentryLogs: true, + + beforeSendLog(log) { + // Prevent logs from being sent to Sentry if the plan type is enterprise + if (log.attributes["plan.type"] === "enterprise") { + return null; + } + + return log; + }, +}); +``` + +At the current moment, logs are not sampled so no sampling configuration needs to be exposed. This may change in the future. + +### Logger Module + +At minimum the SDK needs to implement the following two items to be considered to have a complete logging public API: + +1. `Sentry.logger.X` (where `X` is the log level): The log levels are `trace`, `debug`, `info`, `warn`, `error`, and `fatal`, which is specced out by the [protocol below](#log-severity-level). These methods accepts a string template and the parameters to that string template so the SDK can perform structured logging. Optionally these methods take arbitrary attributes, but not all languages can support both passing a parameterized template and attributes in an easy way. + +- `Sentry.logger.trace` +- `Sentry.logger.debug` +- `Sentry.logger.info` +- `Sentry.logger.warn` +- `Sentry.logger.error` +- `Sentry.logger.fatal` + +```js +Sentry.logger.info`Adding item ${itemId} for user ${userId}`; + +Sentry.logger.warn("User %s performed action %s", [userId, actionName], { + extra: "123", +}); +``` + +2. `Sentry.logger.emit`: A more verbose version of the `Sentry.logger.X` methods that accepts a log object/dictionary for maximum customizability. This is only meant to be used by power users, who want full control over what exactly is being set. Note that this API aligns with [OTEL's default logging API](https://opentelemetry.io/docs/specs/otel/logs/api/#emit-a-logrecord) as well, which gives us flexibility to align on those in the future. + +Emit should take the following parameters: + +- `level`: The log severity level of the log. One of `trace`, `debug`, `info`, `warn`, `error`, `fatal`. +- `message`: The log body +- `attributes`: An object/dictionary of key-value pairs of arbitrary data attached to the log. This should not be a nested data structure. If a object or dictionary is passed in, SDKs can choose to either disregard the attribute, or serialize the object into a string. +- `severityNumber`: An optional integer that represents the severity of the log. See [Log Severity Number](#log-severity-number) for more information. + +```js +Sentry.logger.emit({ + level: "info", + message: "Adding item for user", + attributes: { + itemId, + userId, + }, + severityNumber: 11, +}); +``` + +Beyond the two specified sets of methods, SDKs are free to add any extra helpers as they feel is necessary. For example, they could choose to add specialized decorators or helpers for string template creation. + +Below are some example SDK implementations to get you started. These are not finalized versions of the API and individual SDK authors should ensure the logging APIs best fit their platforms. When an SDK implements the logging API, this section should be updated with the SDK's specific implementation. + +#### JavaScript + +```jsx +// Browser JavaScript - need to rely on tagged template literals for string templating +Sentry.logger.info(Sentry.logger.fmt`Adding item ${itemId} for user ${userId}`); + +// Server-side (Node.js, Bun, Deno) with printf-like syntax +Sentry.logger.info("Adding item %s for user %s", [itemId, userId], { + extra: 123, +}); + +Sentry.logger.emit({ + level: "info", + message: "Adding item for user", + attributes: { + itemId, + userId, + extra: 123, + }, +}); +``` + +#### Python + +```python +# With f-string like syntax +Sentry.logger.info('Adding item {item} for user {user}', item=item_id, user=user_id, attributes={ 'extra': 123 }); + +Sentry.logger.emit( + level='info', + message='Adding item for user', + attributes={ + 'item_id': item_id, + 'user_id': user_id, + extra: 123 + }, +) +``` + +#### PHP + +```php +use function Sentry\logger; + +logger()->info('Adding item %s for user %s', [$item_id, $user_id], ['extra' => 123]); + +logger()->emit( + level: LogLevel::info(), + message: 'Adding item for user', + attributes: [ + 'item_id': item_id, + 'user_id': user_id, + 'extra': 123 + ], +); +``` + +#### Java + +```java +import io.sentry.Sentry; + +// example with MessageFormat based string template +Sentry.logger().info("Adding item {0,string} for user {1,string}", item_id, user_id); + +Sentry.logger().emit(log -> { + log.setLevel("info"); + log.setMessage("Adding item for user"); + log.setAttribute("item_id", item_id); + log.setAttribute("user_id", user_id); + log.setAttribute("extra", 123); +}); + +// Java - Builder Pattern, where setters return builder for method chaining +Sentry.Logger.emit(log -> { + log.setLevel("info") + .setMessage("Adding item for user") + .setAttribute("item_id", item_id) + .setAttribute("user_id", user_id) + .setAttribute("extra", 123) +}); + +// Kotlin +Sentry.Logger.emit("Adding item for user") { // fun emit(block: LogItem.() -> Unit) + setLevel("info") + setAttribute("item_id", item_id) + setAttribute("user_id", user_id) + setAttribute("extra", 123) +} +``` + +#### Apple + +```swift +// Swift +SentrySDK.logger + .info(message: "Adding item %s for user %s", + params: [itemId, userId], + attributes: ["extra": @"123"] + ) + +// Objective-C +[SentrySDK.logger + emit :@"Adding item for user" + level: @"info" + attributes: @{ @"extra" : @"123", @"item_id" : item_id, @"user_id" : user_id } +]; +``` + +#### Threading and Concurrency Considerations + +Both the `Sentry.logger.X` and `Sentry.logger.emit` methods are fire-and-forget (have no return value). This means that the SDK can choose to run these methods on a separate thread or queue them up for processing later. This includes evaluating the string template, and running any internal hooks (like `beforeSendLog`). The SDK should ensure that the logs are sent in the order they are received. + +## SDK behavior + +### Implementation + +If `debug` is set to `true` in SDK init, calls to the Sentry logger API should also print to the console with the appropriate log level. This will help debugging logging setups. + +Logs should be buffered before being sent. SDKs should keep a buffer of logs on the client (so you can have logs from multiple traces in the buffer) that flushes out based on some kind of condition. A recommended condition is if the buffer length exceeds 25 items, or if 5 seconds have passed. In the future we can use a [weight-tracking based approach](https://github.com/getsentry/rfcs/blob/main/text/0126-sdk-spans-aggregator.md#weight) to determine when to flush logs. + +We recommend exposing + +The internal SDK implementation is kept purposefully broad as we are still in early stages. As we figure more out about the logs product and payload characteristics, we'll be able to define a more rigorous spec for logging internals in the SDK. SDKs should take care to not expose logging internals as much as possible to userland so that they can be refactored in the future. + +### Default Attributes + +By default the SDK should set the following attributes: + +1. `sentry.message.template`: The parameterized template string +2. `sentry.message.parameters.X`: The parameters to the template string, where X is the number that represent the parameters position in the template string +3. `sentry.environment`: The environment set in the SDK +4. `sentry.release`: The release set in the SDK + +Example: + +```json +{ + "sentry.message.template": "Adding item %s for user %s", + "sentry.message.parameters.0": "item_id", + "sentry.message.parameters.1": "user_id", + "sentry.environment": "production", + "sentry.release": "1.0.0" +} +``` + +Beyond these attributes, we are exploring if the SDK should also send OS, user, and device information automatically (via reading the appropriate contexts from the scope). Given this behaviour can easily be added as a new feature to the SDK, it does not have to be part of the initial SDK implementation until we make a finalized decision. + +### SDK Integrations + +SDKs should aim to have it so that console/logger integrations create logs as per the appropriate log level if `enableSentryLogs` is set to true. Examples of this include JavaScript's `console` methods and Pythons `logging` standard library. + +If SDK authors feel the need, they can also introduce additional options to beyond `enableSentryLogs` to gate this functionality. For example an option to control log appenders added via external config like with `Log4j` in the Java SDK. + +### Default Attributes From a6a809137d62bf7a38cf1cbe1b12b63408f51143 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Wed, 5 Mar 2025 15:00:03 -0500 Subject: [PATCH 02/28] feat: Document otel_log envelope --- .../sdk/data-model/envelope-items.mdx | 35 +++++- develop-docs/sdk/telemetry/logs.mdx | 116 +++++++++++++++++- 2 files changed, 146 insertions(+), 5 deletions(-) diff --git a/develop-docs/sdk/data-model/envelope-items.mdx b/develop-docs/sdk/data-model/envelope-items.mdx index 32b7d041955c0..29ef867d9757c 100644 --- a/develop-docs/sdk/data-model/envelope-items.mdx +++ b/develop-docs/sdk/data-model/envelope-items.mdx @@ -429,8 +429,41 @@ details. ### Logs -Item type `"logs"` contains a check-in payload encoded as JSON. +Item type `"logs"` contains a logs payload encoded as JSON. Multiple log envelope items can be sent in a single envelope. +See the Logs documentation for the payload +details. + +**Constraints:** + +*None* + +**Envelope Headers:** + +*None* + +**Additional Item Headers:** + +*None* + +### Otel Logs + +Item type `"otel_logs"` contains a OpenTelemetry Logs payload encoded as JSON. Multiple Otel log envelope items can be sent in a single envelope. + +See the Logs documentation for the payload +details. + +**Constraints:** + +*None* + +**Envelope Headers:** + +*None* + +**Additional Item Headers:** + +*None* ### Reserved Types diff --git a/develop-docs/sdk/telemetry/logs.mdx b/develop-docs/sdk/telemetry/logs.mdx index 26f3be39f873d..bbd924da17902 100644 --- a/develop-docs/sdk/telemetry/logs.mdx +++ b/develop-docs/sdk/telemetry/logs.mdx @@ -13,9 +13,102 @@ This document defines the format used by Sentry to ingest logs, as well as the S ## Logs Protocol -Logs can be sent in two ways to Sentry, via the `logs` envelope and Sentry Log Schema, or the `otel_log` envelope and OpenTelemetry Log Schema. The `logs` envelope is the preferred way to send logs to Sentry, but the `otel_log` envelope is also supported. +Logs can be sent in two ways to Sentry, via the `log` envelope and Sentry Log protocol, or the `otel_log` envelope and OpenTelemetry Log protocol. The `log` envelope and protocol is the preferred way to send logs to Sentry, but the `otel_log` envelope and protocol is also supported. -### `logs` Envelope +### `otel_log` Envelope Item Payload + +The `otel_log` envelope item payload is a JSON object that represents a OpenTelemetry Log. Multiple `otel_log` envelope items can be sent in a single envelope. + +```json +{ + "severity_text": "info", + "body": { + "string_value": "User John has logged in!" + }, + "attributes": [ + { + "key": "sentry.message.template", + "value": { "string_value": "User %s has logged in!" } + }, + { + "key": "sentry.message.parameters.0", + "value": { "string_value": "John" } + } + ], + "time_unix_nano": "1741191250694000000", + "trace_id": "edec519707974fc8bfccb5a017e17394", + "severity_number": 9 +} +``` + +It consists of the following fields: + +`severity_text` + +: **String, required**. The severity level of the log. One of `trace`, `debug`, `info`, `warn`, `error`, `fatal` (in order of lowest to highest). + +`severity_number` + +: **Integer, optional**. The severity number of the log. See [Log Severity Number](#log-severity-number) for more information. + +`trace_id` + +: **Integer, optional**. [HEAVILY RECOMMENDED] The trace id of the log. SDKs should attempt to set this if possible. This is used to link logs to traces and errors in Sentry. + +`body` + +: **Object, required**. The log body/message. + +Example: + +```json +{ + "string_value": "Added item to shopping cart" +} +``` + +`attributes` + +: **Array\, optional**. A dictionary of key-value pairs of arbitrary data attached to the log. Attributes must also declare the type of the value. The following types are supported: `string`, `number`, `boolean`, `integer`, `double`. + +Example: + +```json +{ + "attributes": [ + { + "key": "string_item", + "value": { + "stringValue": "value" + } + }, + { + "key": "integer_item", + "value": { + "intValue": 123 + } + }, + { + "key": "boolean_value", + "value": { + "boolValue": false + } + }, + { + "key": "double_item", + "value": { + "stringValue": "value" + } + } + ] +} +``` + +### `log` Envelope Item Payload + +The `log` envelope item payload is a JSON object that represents a log. + +TODO: Document `log` Envelope Item Payload once finalized. ### Log Severity Level @@ -30,6 +123,23 @@ The log severity level is a string that represents the severity of the log. The Optionally the SDK can define a `log` log severity level, which maps to the `info` log severity level in Sentry. +### Log Severity Number + +The log severity number is an integer that represents the severity of the log. The Sentry's default log severity number maps exactly to [OpenTelemetry's Severity number field](https://opentelemetry.io/docs/specs/otel/logs/data-model/#field-severitynumber) on the OpenTelemetry Logs Spec. + +| SeverityNumer range | Range name | Meaning | +| ------------------- | ---------- | --------------------------------------------------------------------------------------- | +| 1-4 | Trace | A fine-grained debugging event. Typically disabled in default configurations. | +| 5-8 | Debug | A debugging event. | +| 9-12 | Info | An informational event. Indicates that an event happened. | +| 13-16 | Warn | A warning event. Not an error but is likely more important than an informational event. | +| 17-20 | Error | An error event. Something went wrong. | +| 21-24 | Fatal | A fatal error such as application or system crash. | + +Default SDK public API should set the lowest severity number for a given severity level. For example, `warn` severity level logs collected by the SDK should use the severity number `13`. + +If an SDK collects `log` severity level, it should map to `info` severity level and `9` severity number. + ## Public API API wise the SDKs are required to expose logging methods which are to be defined in a `logger` module or namespace. The SDKs should also include some initialization options to configure the behavior of logs in the SDK. @@ -226,8 +336,6 @@ If `debug` is set to `true` in SDK init, calls to the Sentry logger API should a Logs should be buffered before being sent. SDKs should keep a buffer of logs on the client (so you can have logs from multiple traces in the buffer) that flushes out based on some kind of condition. A recommended condition is if the buffer length exceeds 25 items, or if 5 seconds have passed. In the future we can use a [weight-tracking based approach](https://github.com/getsentry/rfcs/blob/main/text/0126-sdk-spans-aggregator.md#weight) to determine when to flush logs. -We recommend exposing - The internal SDK implementation is kept purposefully broad as we are still in early stages. As we figure more out about the logs product and payload characteristics, we'll be able to define a more rigorous spec for logging internals in the SDK. SDKs should take care to not expose logging internals as much as possible to userland so that they can be refactored in the future. ### Default Attributes From 20cfb449f6ecb162e2d3b050be089f00ac43c98b Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Wed, 5 Mar 2025 15:05:31 -0500 Subject: [PATCH 03/28] ref: Clean up logs spec --- develop-docs/sdk/telemetry/logs.mdx | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/develop-docs/sdk/telemetry/logs.mdx b/develop-docs/sdk/telemetry/logs.mdx index bbd924da17902..77818aee93a13 100644 --- a/develop-docs/sdk/telemetry/logs.mdx +++ b/develop-docs/sdk/telemetry/logs.mdx @@ -104,6 +104,10 @@ Example: } ``` +`time_unix_nano` + +: **String, optional**. The time the log was created in Unix nanoseconds. If not set, the SDK should set this to the current time. + ### `log` Envelope Item Payload The `log` envelope item payload is a JSON object that represents a log. @@ -121,8 +125,6 @@ The log severity level is a string that represents the severity of the log. The - `error` - `fatal` -Optionally the SDK can define a `log` log severity level, which maps to the `info` log severity level in Sentry. - ### Log Severity Number The log severity number is an integer that represents the severity of the log. The Sentry's default log severity number maps exactly to [OpenTelemetry's Severity number field](https://opentelemetry.io/docs/specs/otel/logs/data-model/#field-severitynumber) on the OpenTelemetry Logs Spec. @@ -136,9 +138,7 @@ The log severity number is an integer that represents the severity of the log. T | 17-20 | Error | An error event. Something went wrong. | | 21-24 | Fatal | A fatal error such as application or system crash. | -Default SDK public API should set the lowest severity number for a given severity level. For example, `warn` severity level logs collected by the SDK should use the severity number `13`. - -If an SDK collects `log` severity level, it should map to `info` severity level and `9` severity number. +Default SDK public API should set the lowest severity number for a given severity level. For example, `warn` severity level logs collected by the SDK API should use the severity number `13`. ## Public API @@ -150,7 +150,7 @@ The SDKs need to expose the following two configuration options: - `enableSentryLogs`/`enable_sentry_logs`: A boolean flag to control if log envelopes will be generated and sent to Sentry via the Sentry SDK's Logging APIs. If this flag is set to `false`, the SDK should not send logs to Sentry. Defaults to `false`. -- `beforeSendLog`/`before_send_log`: A function that takes a log object and returns a log object. This function is called before sending the log to Sentry. It can be used to modify the log object or to prevent the log from being sent to Sentry. Defaults to `null`/`unset`. +- `beforeSendLog`/`before_send_log`: A function that takes a log object and returns a log object. This function is called before sending the log to Sentry. It can be used to modify the log object or to prevent the log from being sent to Sentry. ```js Sentry.init({ @@ -173,7 +173,7 @@ At the current moment, logs are not sampled so no sampling configuration needs t At minimum the SDK needs to implement the following two items to be considered to have a complete logging public API: -1. `Sentry.logger.X` (where `X` is the log level): The log levels are `trace`, `debug`, `info`, `warn`, `error`, and `fatal`, which is specced out by the [protocol below](#log-severity-level). These methods accepts a string template and the parameters to that string template so the SDK can perform structured logging. Optionally these methods take arbitrary attributes, but not all languages can support both passing a parameterized template and attributes in an easy way. +1. `Sentry.logger.X` (where `X` is the log level): The log levels are `trace`, `debug`, `info`, `warn`, `error`, and `fatal`, which is specced out by the [protocol below](#log-severity-level). - `Sentry.logger.trace` - `Sentry.logger.debug` @@ -182,14 +182,23 @@ At minimum the SDK needs to implement the following two items to be considered t - `Sentry.logger.error` - `Sentry.logger.fatal` +These methods accepts a string template and the parameters to that string template so the SDK can perform structured logging. Optionally these methods take arbitrary attributes, but not all languages can support both passing a parameterized template and attributes in an easy way. + ```js -Sentry.logger.info`Adding item ${itemId} for user ${userId}`; +// Need to use `fmt` helper function in JavaScript for structured logging. +Sentry.logger.info(Sentry.logger.fmt`Adding item ${itemId} for user ${userId}`); Sentry.logger.warn("User %s performed action %s", [userId, actionName], { extra: "123", }); ``` +Optionally the SDK can define a `log` log severity level, which maps to the `info` log severity level in Sentry. If an SDK collects `log` severity level, it should map to `info` severity level and `9` severity number. + +```js +Sentry.logger.log("Added item to shopping cart"); +``` + 2. `Sentry.logger.emit`: A more verbose version of the `Sentry.logger.X` methods that accepts a log object/dictionary for maximum customizability. This is only meant to be used by power users, who want full control over what exactly is being set. Note that this API aligns with [OTEL's default logging API](https://opentelemetry.io/docs/specs/otel/logs/api/#emit-a-logrecord) as well, which gives us flexibility to align on those in the future. Emit should take the following parameters: @@ -328,7 +337,7 @@ SentrySDK.logger Both the `Sentry.logger.X` and `Sentry.logger.emit` methods are fire-and-forget (have no return value). This means that the SDK can choose to run these methods on a separate thread or queue them up for processing later. This includes evaluating the string template, and running any internal hooks (like `beforeSendLog`). The SDK should ensure that the logs are sent in the order they are received. -## SDK behavior +## SDK Behavior ### Implementation @@ -366,5 +375,3 @@ Beyond these attributes, we are exploring if the SDK should also send OS, user, SDKs should aim to have it so that console/logger integrations create logs as per the appropriate log level if `enableSentryLogs` is set to true. Examples of this include JavaScript's `console` methods and Pythons `logging` standard library. If SDK authors feel the need, they can also introduce additional options to beyond `enableSentryLogs` to gate this functionality. For example an option to control log appenders added via external config like with `Log4j` in the Java SDK. - -### Default Attributes From ba6d2ddac01b2fc52e10463bb2d391d3451bf7d4 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Wed, 5 Mar 2025 15:15:14 -0500 Subject: [PATCH 04/28] fix link to logs pages --- develop-docs/sdk/data-model/envelope-items.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/develop-docs/sdk/data-model/envelope-items.mdx b/develop-docs/sdk/data-model/envelope-items.mdx index 29ef867d9757c..0c2a8ce3816ff 100644 --- a/develop-docs/sdk/data-model/envelope-items.mdx +++ b/develop-docs/sdk/data-model/envelope-items.mdx @@ -431,7 +431,7 @@ details. Item type `"logs"` contains a logs payload encoded as JSON. Multiple log envelope items can be sent in a single envelope. -See the Logs documentation for the payload +See the Logs documentation for the payload details. **Constraints:** @@ -450,7 +450,7 @@ details. Item type `"otel_logs"` contains a OpenTelemetry Logs payload encoded as JSON. Multiple Otel log envelope items can be sent in a single envelope. -See the Logs documentation for the payload +See the Logs documentation for the payload details. **Constraints:** From 7e4a0cb604daee58a3e10b821543cde9d10561eb Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Thu, 6 Mar 2025 09:47:58 -0500 Subject: [PATCH 05/28] Apply suggestions from code review Co-authored-by: Alex Krawiec --- develop-docs/sdk/data-model/envelope-items.mdx | 2 +- develop-docs/sdk/telemetry/logs.mdx | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/develop-docs/sdk/data-model/envelope-items.mdx b/develop-docs/sdk/data-model/envelope-items.mdx index 0c2a8ce3816ff..8d4074353b2fb 100644 --- a/develop-docs/sdk/data-model/envelope-items.mdx +++ b/develop-docs/sdk/data-model/envelope-items.mdx @@ -448,7 +448,7 @@ details. ### Otel Logs -Item type `"otel_logs"` contains a OpenTelemetry Logs payload encoded as JSON. Multiple Otel log envelope items can be sent in a single envelope. +Item type `"otel_logs"` contains an OpenTelemetry Logs payload encoded as JSON. Multiple Otel log envelope items can be sent in a single envelope. See the Logs documentation for the payload details. diff --git a/develop-docs/sdk/telemetry/logs.mdx b/develop-docs/sdk/telemetry/logs.mdx index 77818aee93a13..8f0392fa8bdce 100644 --- a/develop-docs/sdk/telemetry/logs.mdx +++ b/develop-docs/sdk/telemetry/logs.mdx @@ -9,15 +9,15 @@ The Sentry Logs feature is under active development. The information in this doc -This document defines the format used by Sentry to ingest logs, as well as the SDK API and behavior that creates and sends logs to Sentry. +This document defines the format used by Sentry to ingest logs, as well as the SDK API and behavior that create and send logs to Sentry. ## Logs Protocol -Logs can be sent in two ways to Sentry, via the `log` envelope and Sentry Log protocol, or the `otel_log` envelope and OpenTelemetry Log protocol. The `log` envelope and protocol is the preferred way to send logs to Sentry, but the `otel_log` envelope and protocol is also supported. +There are two ways to send logs to Sentry: via the `log` envelope and Sentry Log protocol (preferred), or the `otel_log` envelope and OpenTelemetry Log protocol. ### `otel_log` Envelope Item Payload -The `otel_log` envelope item payload is a JSON object that represents a OpenTelemetry Log. Multiple `otel_log` envelope items can be sent in a single envelope. +The `otel_log` envelope item payload is a JSON object that represents an OpenTelemetry Log. Multiple `otel_log` envelope items can be sent in a single envelope. ```json { From e5f87ea7ba14ffc8700e56c41938a6fcde89bd4d Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Thu, 6 Mar 2025 10:14:14 -0500 Subject: [PATCH 06/28] Update develop-docs/sdk/telemetry/logs.mdx Co-authored-by: Lorenzo Cian --- develop-docs/sdk/telemetry/logs.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/develop-docs/sdk/telemetry/logs.mdx b/develop-docs/sdk/telemetry/logs.mdx index 8f0392fa8bdce..21e5b871751f4 100644 --- a/develop-docs/sdk/telemetry/logs.mdx +++ b/develop-docs/sdk/telemetry/logs.mdx @@ -129,7 +129,7 @@ The log severity level is a string that represents the severity of the log. The The log severity number is an integer that represents the severity of the log. The Sentry's default log severity number maps exactly to [OpenTelemetry's Severity number field](https://opentelemetry.io/docs/specs/otel/logs/data-model/#field-severitynumber) on the OpenTelemetry Logs Spec. -| SeverityNumer range | Range name | Meaning | +| SeverityNumber range | Range name | Meaning | | ------------------- | ---------- | --------------------------------------------------------------------------------------- | | 1-4 | Trace | A fine-grained debugging event. Typically disabled in default configurations. | | 5-8 | Debug | A debugging event. | From cc48024004aa9668cf242c61101462be6470fb97 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Tue, 11 Mar 2025 09:06:43 -0400 Subject: [PATCH 07/28] Update develop-docs/sdk/telemetry/logs.mdx --- develop-docs/sdk/telemetry/logs.mdx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/develop-docs/sdk/telemetry/logs.mdx b/develop-docs/sdk/telemetry/logs.mdx index 21e5b871751f4..548faa31c6d29 100644 --- a/develop-docs/sdk/telemetry/logs.mdx +++ b/develop-docs/sdk/telemetry/logs.mdx @@ -355,6 +355,7 @@ By default the SDK should set the following attributes: 2. `sentry.message.parameters.X`: The parameters to the template string, where X is the number that represent the parameters position in the template string 3. `sentry.environment`: The environment set in the SDK 4. `sentry.release`: The release set in the SDK +5. `sentry.trace.parent_span_id`: The span id of the span that was active when the log was collected. This should not be set if there was no active span. Example: @@ -364,9 +365,9 @@ Example: "sentry.message.parameters.0": "item_id", "sentry.message.parameters.1": "user_id", "sentry.environment": "production", - "sentry.release": "1.0.0" + "sentry.release": "1.0.0", + "sentry.trace.parent_span_id": "b0e6f15b45c36b12" } -``` Beyond these attributes, we are exploring if the SDK should also send OS, user, and device information automatically (via reading the appropriate contexts from the scope). Given this behaviour can easily be added as a new feature to the SDK, it does not have to be part of the initial SDK implementation until we make a finalized decision. From 0540762a41161819799684c4c8c82fc31fc18d4a Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Tue, 11 Mar 2025 09:07:31 -0400 Subject: [PATCH 08/28] fix: close code block --- develop-docs/sdk/telemetry/logs.mdx | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/develop-docs/sdk/telemetry/logs.mdx b/develop-docs/sdk/telemetry/logs.mdx index 548faa31c6d29..2f3dd312eddfe 100644 --- a/develop-docs/sdk/telemetry/logs.mdx +++ b/develop-docs/sdk/telemetry/logs.mdx @@ -130,13 +130,13 @@ The log severity level is a string that represents the severity of the log. The The log severity number is an integer that represents the severity of the log. The Sentry's default log severity number maps exactly to [OpenTelemetry's Severity number field](https://opentelemetry.io/docs/specs/otel/logs/data-model/#field-severitynumber) on the OpenTelemetry Logs Spec. | SeverityNumber range | Range name | Meaning | -| ------------------- | ---------- | --------------------------------------------------------------------------------------- | -| 1-4 | Trace | A fine-grained debugging event. Typically disabled in default configurations. | -| 5-8 | Debug | A debugging event. | -| 9-12 | Info | An informational event. Indicates that an event happened. | -| 13-16 | Warn | A warning event. Not an error but is likely more important than an informational event. | -| 17-20 | Error | An error event. Something went wrong. | -| 21-24 | Fatal | A fatal error such as application or system crash. | +| -------------------- | ---------- | --------------------------------------------------------------------------------------- | +| 1-4 | Trace | A fine-grained debugging event. Typically disabled in default configurations. | +| 5-8 | Debug | A debugging event. | +| 9-12 | Info | An informational event. Indicates that an event happened. | +| 13-16 | Warn | A warning event. Not an error but is likely more important than an informational event. | +| 17-20 | Error | An error event. Something went wrong. | +| 21-24 | Fatal | A fatal error such as application or system crash. | Default SDK public API should set the lowest severity number for a given severity level. For example, `warn` severity level logs collected by the SDK API should use the severity number `13`. @@ -368,6 +368,7 @@ Example: "sentry.release": "1.0.0", "sentry.trace.parent_span_id": "b0e6f15b45c36b12" } +``` Beyond these attributes, we are exploring if the SDK should also send OS, user, and device information automatically (via reading the appropriate contexts from the scope). Given this behaviour can easily be added as a new feature to the SDK, it does not have to be part of the initial SDK implementation until we make a finalized decision. From 07f741b702e51bdf4a87d14aa8bdf9165044a38d Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Tue, 11 Mar 2025 11:44:55 -0400 Subject: [PATCH 09/28] fix: Specify that intValue is a string --- develop-docs/sdk/telemetry/logs.mdx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/develop-docs/sdk/telemetry/logs.mdx b/develop-docs/sdk/telemetry/logs.mdx index 2f3dd312eddfe..20746b1daf5ff 100644 --- a/develop-docs/sdk/telemetry/logs.mdx +++ b/develop-docs/sdk/telemetry/logs.mdx @@ -71,6 +71,8 @@ Example: : **Array\, optional**. A dictionary of key-value pairs of arbitrary data attached to the log. Attributes must also declare the type of the value. The following types are supported: `string`, `number`, `boolean`, `integer`, `double`. +Note: `intValue` is a string because JSON only recognizes numbers as floating point numbers. The SDK should convert the string to a number when sending the log to Sentry if setting as `intValue`. + Example: ```json @@ -85,7 +87,7 @@ Example: { "key": "integer_item", "value": { - "intValue": 123 + "intValue": "123" } }, { From 60c3bdcf35e05a0fc7abc70d60bd1cd38d556837 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Tue, 11 Mar 2025 11:48:40 -0400 Subject: [PATCH 10/28] fix: Cursor got the change wrong --- develop-docs/sdk/telemetry/logs.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/develop-docs/sdk/telemetry/logs.mdx b/develop-docs/sdk/telemetry/logs.mdx index 20746b1daf5ff..d33e8cb51d5b5 100644 --- a/develop-docs/sdk/telemetry/logs.mdx +++ b/develop-docs/sdk/telemetry/logs.mdx @@ -71,7 +71,7 @@ Example: : **Array\, optional**. A dictionary of key-value pairs of arbitrary data attached to the log. Attributes must also declare the type of the value. The following types are supported: `string`, `number`, `boolean`, `integer`, `double`. -Note: `intValue` is a string because JSON only recognizes numbers as floating point numbers. The SDK should convert the string to a number when sending the log to Sentry if setting as `intValue`. +Note: `intValue` is a string because JSON only recognizes numbers as floating point values. Example: @@ -99,7 +99,7 @@ Example: { "key": "double_item", "value": { - "stringValue": "value" + "doubleValue": "value" } } ] From 3ff6e568b5e40648b49c2d64240e45dfb12ae63d Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Thu, 20 Mar 2025 13:12:49 -0400 Subject: [PATCH 11/28] Document log envelope item payload --- .../sdk/data-model/envelope-items.mdx | 4 +- develop-docs/sdk/telemetry/logs.mdx | 203 ++++++++++++------ 2 files changed, 141 insertions(+), 66 deletions(-) diff --git a/develop-docs/sdk/data-model/envelope-items.mdx b/develop-docs/sdk/data-model/envelope-items.mdx index 8d4074353b2fb..0f0a28a0ea8e1 100644 --- a/develop-docs/sdk/data-model/envelope-items.mdx +++ b/develop-docs/sdk/data-model/envelope-items.mdx @@ -429,7 +429,7 @@ details. ### Logs -Item type `"logs"` contains a logs payload encoded as JSON. Multiple log envelope items can be sent in a single envelope. +Item type `"log"` contains a logs payload encoded as JSON. Multiple log envelope items can be sent in a single envelope. See the Logs documentation for the payload details. @@ -448,7 +448,7 @@ details. ### Otel Logs -Item type `"otel_logs"` contains an OpenTelemetry Logs payload encoded as JSON. Multiple Otel log envelope items can be sent in a single envelope. +Item type `"otel_log"` contains an OpenTelemetry Logs payload encoded as JSON. Multiple Otel log envelope items can be sent in a single envelope. See the Logs documentation for the payload details. diff --git a/develop-docs/sdk/telemetry/logs.mdx b/develop-docs/sdk/telemetry/logs.mdx index d33e8cb51d5b5..aaa0bca688d18 100644 --- a/develop-docs/sdk/telemetry/logs.mdx +++ b/develop-docs/sdk/telemetry/logs.mdx @@ -15,61 +15,59 @@ This document defines the format used by Sentry to ingest logs, as well as the S There are two ways to send logs to Sentry: via the `log` envelope and Sentry Log protocol (preferred), or the `otel_log` envelope and OpenTelemetry Log protocol. -### `otel_log` Envelope Item Payload +All SDKs are required to send logs via the `log` envelope and Sentry Log protocol. The `otel_log` envelope and OpenTelemetry Log protocol are just documented for completeness and to provide a reference for SDK authors. See the [Appendix A](#appendix-a-otel_log-envelope-item-payload) for the `otel_log` envelope item payload. -The `otel_log` envelope item payload is a JSON object that represents an OpenTelemetry Log. Multiple `otel_log` envelope items can be sent in a single envelope. +### `log` Envelope Item Payload + +The `log` envelope item payload is a JSON object that represents a Sentry Log. Multiple `log` envelope items can be sent in a single envelope. ```json { - "severity_text": "info", - "body": { - "string_value": "User John has logged in!" - }, - "attributes": [ - { - "key": "sentry.message.template", - "value": { "string_value": "User %s has logged in!" } + "timestamp": 1544719860.0, + "trace_id": "5b8efff798038103d269b633813fc60c", + "level": "info", + "body": "User John has logged in!", + "attributes": { + "sentry.message.template": { + "string_value": "User %s has logged in!" }, - { - "key": "sentry.message.parameters.0", - "value": { "string_value": "John" } + "sentry.message.parameters.0": { + "string_value": "John" + }, + "sentry.environment": { + "string_value": "production" + }, + "sentry.release": { + "string_value": "1.0.0" + }, + "sentry.trace.parent_span_id": { + "string_value": "b0e6f15b45c36b12" } - ], - "time_unix_nano": "1741191250694000000", - "trace_id": "edec519707974fc8bfccb5a017e17394", - "severity_number": 9 + } } ``` It consists of the following fields: -`severity_text` - -: **String, required**. The severity level of the log. One of `trace`, `debug`, `info`, `warn`, `error`, `fatal` (in order of lowest to highest). - -`severity_number` +`timestamp` -: **Integer, optional**. The severity number of the log. See [Log Severity Number](#log-severity-number) for more information. +: **Number, required**. The timestamp of the log in seconds since the Unix epoch. `trace_id` -: **Integer, optional**. [HEAVILY RECOMMENDED] The trace id of the log. SDKs should attempt to set this if possible. This is used to link logs to traces and errors in Sentry. +: **String, required**. The trace id of the log. -`body` +`level` -: **Object, required**. The log body/message. +: **String, required**. The severity level of the log. One of `trace`, `debug`, `info`, `warn`, `error`, `fatal` (in order of lowest to highest). -Example: +`body` -```json -{ - "string_value": "Added item to shopping cart" -} -``` +: **String, required**. The log body/message. `attributes` -: **Array\, optional**. A dictionary of key-value pairs of arbitrary data attached to the log. Attributes must also declare the type of the value. The following types are supported: `string`, `number`, `boolean`, `integer`, `double`. +: **Object, optional**. A dictionary of key-value pairs of arbitrary data attached to the log. Attributes must also declare the type of the value. The following types are supported: `string`, `boolean`, `integer`, `double`. Note: `intValue` is a string because JSON only recognizes numbers as floating point values. @@ -77,48 +75,30 @@ Example: ```json { - "attributes": [ - { - "key": "string_item", - "value": { - "stringValue": "value" - } + "attributes": { + "string_item": { + "stringValue": "value" }, - { - "key": "integer_item", - "value": { - "intValue": "123" - } + "integer_item": { + "intValue": "123" }, - { - "key": "boolean_value", - "value": { - "boolValue": false - } + "boolean_item": { + "boolValue": true }, - { - "key": "double_item", - "value": { - "doubleValue": "value" - } + "double_item": { + "doubleValue": 123.456 } - ] + } } ``` -`time_unix_nano` - -: **String, optional**. The time the log was created in Unix nanoseconds. If not set, the SDK should set this to the current time. - -### `log` Envelope Item Payload - -The `log` envelope item payload is a JSON object that represents a log. +`severity_number` -TODO: Document `log` Envelope Item Payload once finalized. +: **Integer, optional**. The severity number of the log. See [Log Severity Number](#log-severity-number) for more information. This is inferenced from `level` unless explicitly set. ### Log Severity Level -The log severity level is a string that represents the severity of the log. The Sentry's default log severity level maps exactly to [OpenTelemetry's Severity text field](https://opentelemetry.io/docs/specs/otel/logs/data-model/#field-severitytext) on the OpenTelemetry Logs Spec.. +The log severity level is a string that represents the severity of the log. The Sentry's default log severity level maps exactly to [OpenTelemetry's Severity text field](https://opentelemetry.io/docs/specs/otel/logs/data-model/#field-severitytext) on the OpenTelemetry Logs Spec. - `trace` - `debug` @@ -379,3 +359,98 @@ Beyond these attributes, we are exploring if the SDK should also send OS, user, SDKs should aim to have it so that console/logger integrations create logs as per the appropriate log level if `enableSentryLogs` is set to true. Examples of this include JavaScript's `console` methods and Pythons `logging` standard library. If SDK authors feel the need, they can also introduce additional options to beyond `enableSentryLogs` to gate this functionality. For example an option to control log appenders added via external config like with `Log4j` in the Java SDK. + +## Appendix A: `otel_log` Envelope Item Payload + +The `otel_log` envelope item payload is a JSON object that represents an OpenTelemetry Log. Multiple `otel_log` envelope items can be sent in a single envelope. + +```json +{ + "severity_text": "info", + "body": { + "string_value": "User John has logged in!" + }, + "attributes": [ + { + "key": "sentry.message.template", + "value": { "string_value": "User %s has logged in!" } + }, + { + "key": "sentry.message.parameters.0", + "value": { "string_value": "John" } + } + ], + "time_unix_nano": "1741191250694000000", + "trace_id": "edec519707974fc8bfccb5a017e17394", + "severity_number": 9 +} +``` + +It consists of the following fields: + +`severity_text` + +: **String, required**. The severity level of the log. One of `trace`, `debug`, `info`, `warn`, `error`, `fatal` (in order of lowest to highest). + +`severity_number` + +: **Integer, optional**. The severity number of the log. See [Log Severity Number](#log-severity-number) for more information. + +`trace_id` + +: **Integer, optional**. [HEAVILY RECOMMENDED] The trace id of the log. SDKs should attempt to set this if possible. This is used to link logs to traces and errors in Sentry. + +`body` + +: **Object, required**. The log body/message. + +Example: + +```json +{ + "string_value": "Added item to shopping cart" +} +``` + +`attributes` + +: **Array\, optional**. A dictionary of key-value pairs of arbitrary data attached to the log. Attributes must also declare the type of the value. The following types are supported: `string`, `number`, `boolean`, `integer`, `double`. + +Note: `intValue` is a string because JSON only recognizes numbers as floating point values. + +Example: + +```json +{ + "attributes": [ + { + "key": "string_item", + "value": { + "stringValue": "value" + } + }, + { + "key": "integer_item", + "value": { + "intValue": "123" + } + }, + { + "key": "boolean_value", + "value": { + "boolValue": false + } + }, + { + "key": "double_item", + "value": { + "doubleValue": "value" + } + } + ] +} +``` + +`time_unix_nano` + +: **String, optional**. The time the log was created in Unix nanoseconds. If not set, the SDK should set this to the current time. From 2d2abe8372c4d3806c777d3a274585a6f40ea9ae Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Thu, 20 Mar 2025 13:17:54 -0400 Subject: [PATCH 12/28] enable_sentry_logs -> enable_logs --- develop-docs/sdk/telemetry/logs.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/develop-docs/sdk/telemetry/logs.mdx b/develop-docs/sdk/telemetry/logs.mdx index aaa0bca688d18..4fa8b98f4839b 100644 --- a/develop-docs/sdk/telemetry/logs.mdx +++ b/develop-docs/sdk/telemetry/logs.mdx @@ -130,7 +130,7 @@ API wise the SDKs are required to expose logging methods which are to be defined The SDKs need to expose the following two configuration options: -- `enableSentryLogs`/`enable_sentry_logs`: A boolean flag to control if log envelopes will be generated and sent to Sentry via the Sentry SDK's Logging APIs. If this flag is set to `false`, the SDK should not send logs to Sentry. Defaults to `false`. +- `enable_logs`/`enable_logs`: A boolean flag to control if log envelopes will be generated and sent to Sentry via the Sentry SDK's Logging APIs. If this flag is set to `false`, the SDK should not send logs to Sentry. Defaults to `false`. - `beforeSendLog`/`before_send_log`: A function that takes a log object and returns a log object. This function is called before sending the log to Sentry. It can be used to modify the log object or to prevent the log from being sent to Sentry. @@ -362,7 +362,7 @@ If SDK authors feel the need, they can also introduce additional options to beyo ## Appendix A: `otel_log` Envelope Item Payload -The `otel_log` envelope item payload is a JSON object that represents an OpenTelemetry Log. Multiple `otel_log` envelope items can be sent in a single envelope. +The `otel_log` envelope item payload is a JSON object that represents an OpenTelemetry Log. Multiple `otel_log` envelope items can be sent in a single envelope. This is implementation of the [OpenTelemetry Log Data Model](https://opentelemetry.io/docs/specs/otel/logs/data-model/). ```json { From ab38e6e88e187f6fbeb59ba88eac5c54b938edab Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Thu, 20 Mar 2025 13:20:56 -0400 Subject: [PATCH 13/28] note about overloading method --- develop-docs/sdk/telemetry/logs.mdx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/develop-docs/sdk/telemetry/logs.mdx b/develop-docs/sdk/telemetry/logs.mdx index 4fa8b98f4839b..180a9aff2efff 100644 --- a/develop-docs/sdk/telemetry/logs.mdx +++ b/develop-docs/sdk/telemetry/logs.mdx @@ -181,6 +181,8 @@ Optionally the SDK can define a `log` log severity level, which maps to the `inf Sentry.logger.log("Added item to shopping cart"); ``` +These methods can be overloaded to accept severity number or other parameters if required for the language or platform. + 2. `Sentry.logger.emit`: A more verbose version of the `Sentry.logger.X` methods that accepts a log object/dictionary for maximum customizability. This is only meant to be used by power users, who want full control over what exactly is being set. Note that this API aligns with [OTEL's default logging API](https://opentelemetry.io/docs/specs/otel/logs/api/#emit-a-logrecord) as well, which gives us flexibility to align on those in the future. Emit should take the following parameters: From 5ea9d7d6acdb020939e3a751a2f278c1be30cd9d Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Thu, 20 Mar 2025 13:22:14 -0400 Subject: [PATCH 14/28] remove log method --- develop-docs/sdk/telemetry/logs.mdx | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/develop-docs/sdk/telemetry/logs.mdx b/develop-docs/sdk/telemetry/logs.mdx index 180a9aff2efff..b90c4a25aad38 100644 --- a/develop-docs/sdk/telemetry/logs.mdx +++ b/develop-docs/sdk/telemetry/logs.mdx @@ -175,13 +175,7 @@ Sentry.logger.warn("User %s performed action %s", [userId, actionName], { }); ``` -Optionally the SDK can define a `log` log severity level, which maps to the `info` log severity level in Sentry. If an SDK collects `log` severity level, it should map to `info` severity level and `9` severity number. - -```js -Sentry.logger.log("Added item to shopping cart"); -``` - -These methods can be overloaded to accept severity number or other parameters if required for the language or platform. +Aside from accepting attributes, these methods can be overloaded to accept severity number or other parameters if required for the language or platform. 2. `Sentry.logger.emit`: A more verbose version of the `Sentry.logger.X` methods that accepts a log object/dictionary for maximum customizability. This is only meant to be used by power users, who want full control over what exactly is being set. Note that this API aligns with [OTEL's default logging API](https://opentelemetry.io/docs/specs/otel/logs/api/#emit-a-logrecord) as well, which gives us flexibility to align on those in the future. From 9d7302bd7325cc81a63266f03ad0b1affd9b43f0 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Thu, 20 Mar 2025 13:25:35 -0400 Subject: [PATCH 15/28] remove emit --- develop-docs/sdk/telemetry/logs.mdx | 80 ++--------------------------- 1 file changed, 5 insertions(+), 75 deletions(-) diff --git a/develop-docs/sdk/telemetry/logs.mdx b/develop-docs/sdk/telemetry/logs.mdx index b90c4a25aad38..1f1e9abddcbf6 100644 --- a/develop-docs/sdk/telemetry/logs.mdx +++ b/develop-docs/sdk/telemetry/logs.mdx @@ -153,9 +153,7 @@ At the current moment, logs are not sampled so no sampling configuration needs t ### Logger Module -At minimum the SDK needs to implement the following two items to be considered to have a complete logging public API: - -1. `Sentry.logger.X` (where `X` is the log level): The log levels are `trace`, `debug`, `info`, `warn`, `error`, and `fatal`, which is specced out by the [protocol below](#log-severity-level). +At minimum the SDK needs to implement the `Sentry.logger.X` (where `X` is the log level) methods. The log levels are `trace`, `debug`, `info`, `warn`, `error`, and `fatal`, which is specced out by the [protocol below](#log-severity-level). - `Sentry.logger.trace` - `Sentry.logger.debug` @@ -177,28 +175,7 @@ Sentry.logger.warn("User %s performed action %s", [userId, actionName], { Aside from accepting attributes, these methods can be overloaded to accept severity number or other parameters if required for the language or platform. -2. `Sentry.logger.emit`: A more verbose version of the `Sentry.logger.X` methods that accepts a log object/dictionary for maximum customizability. This is only meant to be used by power users, who want full control over what exactly is being set. Note that this API aligns with [OTEL's default logging API](https://opentelemetry.io/docs/specs/otel/logs/api/#emit-a-logrecord) as well, which gives us flexibility to align on those in the future. - -Emit should take the following parameters: - -- `level`: The log severity level of the log. One of `trace`, `debug`, `info`, `warn`, `error`, `fatal`. -- `message`: The log body -- `attributes`: An object/dictionary of key-value pairs of arbitrary data attached to the log. This should not be a nested data structure. If a object or dictionary is passed in, SDKs can choose to either disregard the attribute, or serialize the object into a string. -- `severityNumber`: An optional integer that represents the severity of the log. See [Log Severity Number](#log-severity-number) for more information. - -```js -Sentry.logger.emit({ - level: "info", - message: "Adding item for user", - attributes: { - itemId, - userId, - }, - severityNumber: 11, -}); -``` - -Beyond the two specified sets of methods, SDKs are free to add any extra helpers as they feel is necessary. For example, they could choose to add specialized decorators or helpers for string template creation. +Beyond the specified methods, SDKs are free to add any extra helpers as they feel is necessary. For example, they could choose to add specialized decorators or helpers for string template creation. Below are some example SDK implementations to get you started. These are not finalized versions of the API and individual SDK authors should ensure the logging APIs best fit their platforms. When an SDK implements the logging API, this section should be updated with the SDK's specific implementation. @@ -212,16 +189,6 @@ Sentry.logger.info(Sentry.logger.fmt`Adding item ${itemId} for user ${userId}`); Sentry.logger.info("Adding item %s for user %s", [itemId, userId], { extra: 123, }); - -Sentry.logger.emit({ - level: "info", - message: "Adding item for user", - attributes: { - itemId, - userId, - extra: 123, - }, -}); ``` #### Python @@ -229,16 +196,6 @@ Sentry.logger.emit({ ```python # With f-string like syntax Sentry.logger.info('Adding item {item} for user {user}', item=item_id, user=user_id, attributes={ 'extra': 123 }); - -Sentry.logger.emit( - level='info', - message='Adding item for user', - attributes={ - 'item_id': item_id, - 'user_id': user_id, - extra: 123 - }, -) ``` #### PHP @@ -247,16 +204,6 @@ Sentry.logger.emit( use function Sentry\logger; logger()->info('Adding item %s for user %s', [$item_id, $user_id], ['extra' => 123]); - -logger()->emit( - level: LogLevel::info(), - message: 'Adding item for user', - attributes: [ - 'item_id': item_id, - 'user_id': user_id, - 'extra': 123 - ], -); ``` #### Java @@ -265,28 +212,12 @@ logger()->emit( import io.sentry.Sentry; // example with MessageFormat based string template -Sentry.logger().info("Adding item {0,string} for user {1,string}", item_id, user_id); - -Sentry.logger().emit(log -> { - log.setLevel("info"); - log.setMessage("Adding item for user"); - log.setAttribute("item_id", item_id); - log.setAttribute("user_id", user_id); +Sentry.logger().info("Adding item {0,string} for user {1,string}", item_id, user_id, log -> { log.setAttribute("extra", 123); }); -// Java - Builder Pattern, where setters return builder for method chaining -Sentry.Logger.emit(log -> { - log.setLevel("info") - .setMessage("Adding item for user") - .setAttribute("item_id", item_id) - .setAttribute("user_id", user_id) - .setAttribute("extra", 123) -}); - // Kotlin -Sentry.Logger.emit("Adding item for user") { // fun emit(block: LogItem.() -> Unit) - setLevel("info") +Sentry.Logger.info("Adding item for user") { // fun info(block: LogItem.() -> Unit) setAttribute("item_id", item_id) setAttribute("user_id", user_id) setAttribute("extra", 123) @@ -305,8 +236,7 @@ SentrySDK.logger // Objective-C [SentrySDK.logger - emit :@"Adding item for user" - level: @"info" + info :@"Adding item for user" attributes: @{ @"extra" : @"123", @"item_id" : item_id, @"user_id" : user_id } ]; ``` From 6dc07e630fefce60d3dc66d74be0ae761083af31 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Thu, 20 Mar 2025 13:26:28 -0400 Subject: [PATCH 16/28] remove obj-c --- develop-docs/sdk/telemetry/logs.mdx | 6 ------ 1 file changed, 6 deletions(-) diff --git a/develop-docs/sdk/telemetry/logs.mdx b/develop-docs/sdk/telemetry/logs.mdx index 1f1e9abddcbf6..13579ce38fd46 100644 --- a/develop-docs/sdk/telemetry/logs.mdx +++ b/develop-docs/sdk/telemetry/logs.mdx @@ -233,12 +233,6 @@ SentrySDK.logger params: [itemId, userId], attributes: ["extra": @"123"] ) - -// Objective-C -[SentrySDK.logger - info :@"Adding item for user" - attributes: @{ @"extra" : @"123", @"item_id" : item_id, @"user_id" : user_id } -]; ``` #### Threading and Concurrency Considerations From 28cb4b597e10634dfff7d645b36094af21c19cc4 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Thu, 20 Mar 2025 13:30:48 -0400 Subject: [PATCH 17/28] add note about crashes --- develop-docs/sdk/telemetry/logs.mdx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/develop-docs/sdk/telemetry/logs.mdx b/develop-docs/sdk/telemetry/logs.mdx index 13579ce38fd46..092edf345a224 100644 --- a/develop-docs/sdk/telemetry/logs.mdx +++ b/develop-docs/sdk/telemetry/logs.mdx @@ -239,6 +239,8 @@ SentrySDK.logger Both the `Sentry.logger.X` and `Sentry.logger.emit` methods are fire-and-forget (have no return value). This means that the SDK can choose to run these methods on a separate thread or queue them up for processing later. This includes evaluating the string template, and running any internal hooks (like `beforeSendLog`). The SDK should ensure that the logs are sent in the order they are received. +It's important to note that putting everything immediately on a background thread has the downside of losing logs that occur directly before a crash. This will come up for Mobile SDKs. Therefore there will need to be a more robust mechanism if a separate thread is used. This mechanism will vary by platform, and the individual SDK will need to figure out the best approach for their platform. + ## SDK Behavior ### Implementation From 824a186716371e0423661e16521224bd32653cf1 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Thu, 20 Mar 2025 13:35:17 -0400 Subject: [PATCH 18/28] Document rate limiting and client outcomes --- develop-docs/sdk/telemetry/logs.mdx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/develop-docs/sdk/telemetry/logs.mdx b/develop-docs/sdk/telemetry/logs.mdx index 092edf345a224..ace8301032ade 100644 --- a/develop-docs/sdk/telemetry/logs.mdx +++ b/develop-docs/sdk/telemetry/logs.mdx @@ -249,6 +249,8 @@ If `debug` is set to `true` in SDK init, calls to the Sentry logger API should a Logs should be buffered before being sent. SDKs should keep a buffer of logs on the client (so you can have logs from multiple traces in the buffer) that flushes out based on some kind of condition. A recommended condition is if the buffer length exceeds 25 items, or if 5 seconds have passed. In the future we can use a [weight-tracking based approach](https://github.com/getsentry/rfcs/blob/main/text/0126-sdk-spans-aggregator.md#weight) to determine when to flush logs. +A new data category for logs has been added to Relay, `log_item`. Both the `log` envelope and `otel_log` envelope is covered by this data category. This will need to implemented in the SDK. Rate limiting applies as usual, there is no special rate limit or rate limiting behaviour for logs. With this data category, client outcomes should be tracked by the SDKs to track how often logs are dropped by the SDK. + The internal SDK implementation is kept purposefully broad as we are still in early stages. As we figure more out about the logs product and payload characteristics, we'll be able to define a more rigorous spec for logging internals in the SDK. SDKs should take care to not expose logging internals as much as possible to userland so that they can be refactored in the future. ### Default Attributes From 9a130c14232b0d898894a92a6bf704bf8422f797 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Thu, 27 Mar 2025 12:55:40 -0400 Subject: [PATCH 19/28] update spec based on attribute changes --- develop-docs/sdk/telemetry/logs.mdx | 43 +++++++++++++++++------------ 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/develop-docs/sdk/telemetry/logs.mdx b/develop-docs/sdk/telemetry/logs.mdx index ace8301032ade..25f08502863eb 100644 --- a/develop-docs/sdk/telemetry/logs.mdx +++ b/develop-docs/sdk/telemetry/logs.mdx @@ -29,19 +29,24 @@ The `log` envelope item payload is a JSON object that represents a Sentry Log. M "body": "User John has logged in!", "attributes": { "sentry.message.template": { - "string_value": "User %s has logged in!" + "value": "User %s has logged in!", + "type": "string" }, "sentry.message.parameters.0": { - "string_value": "John" + "value": "John", + "type": "string" }, "sentry.environment": { - "string_value": "production" + "value": "production", + "type": "string" }, "sentry.release": { - "string_value": "1.0.0" + "value": "1.0.0", + "type": "string" }, "sentry.trace.parent_span_id": { - "string_value": "b0e6f15b45c36b12" + "value": "b0e6f15b45c36b12", + "type": "string" } } } @@ -69,24 +74,28 @@ It consists of the following fields: : **Object, optional**. A dictionary of key-value pairs of arbitrary data attached to the log. Attributes must also declare the type of the value. The following types are supported: `string`, `boolean`, `integer`, `double`. -Note: `intValue` is a string because JSON only recognizes numbers as floating point values. +Note: `type: "integer"` has string values because JSON only recognizes numbers as floating point values. Example: ```json { "attributes": { - "string_item": { - "stringValue": "value" + "db.namespace": { + "value": "projects", + "type": "string" }, - "integer_item": { - "intValue": "123" + "db.response.returned_rows": { + "value": "123", + "type": "integer" }, - "boolean_item": { - "boolValue": true + "db_query_processing_time": { + "value": 123.456, + "type": "double" }, - "double_item": { - "doubleValue": 123.456 + "is_production_db": { + "value": false, + "type": "boolean" } } } @@ -136,7 +145,7 @@ The SDKs need to expose the following two configuration options: ```js Sentry.init({ - enableSentryLogs: true, + enableLogs: true, beforeSendLog(log) { // Prevent logs from being sent to Sentry if the plan type is enterprise @@ -280,9 +289,9 @@ Beyond these attributes, we are exploring if the SDK should also send OS, user, ### SDK Integrations -SDKs should aim to have it so that console/logger integrations create logs as per the appropriate log level if `enableSentryLogs` is set to true. Examples of this include JavaScript's `console` methods and Pythons `logging` standard library. +SDKs should aim to have it so that console/logger integrations create logs as per the appropriate log level if `enableLogs` is set to true. Examples of this include JavaScript's `console` object and Pythons `logging` standard library. -If SDK authors feel the need, they can also introduce additional options to beyond `enableSentryLogs` to gate this functionality. For example an option to control log appenders added via external config like with `Log4j` in the Java SDK. +If SDK authors feel the need, they can also introduce additional options to beyond `enableLogs` to gate this functionality. For example an option to control log appenders added via external config like with `Log4j` in the Java SDK. ## Appendix A: `otel_log` Envelope Item Payload From 021d442f5508f4ab3e21bacb2b1908f2793bf0ce Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Mon, 7 Apr 2025 10:45:21 +0200 Subject: [PATCH 20/28] document sentry.origin log attribute --- develop-docs/sdk/telemetry/logs.mdx | 8 +++++++ .../sdk/telemetry/traces/trace-origin.mdx | 21 +++++++++++-------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/develop-docs/sdk/telemetry/logs.mdx b/develop-docs/sdk/telemetry/logs.mdx index 25f08502863eb..2b172c81d5007 100644 --- a/develop-docs/sdk/telemetry/logs.mdx +++ b/develop-docs/sdk/telemetry/logs.mdx @@ -285,6 +285,14 @@ Example: } ``` +If a log is generated by an SDK integration, the SDK should also set the `sentry.origin` attribute, as per the [Trace Origin](./traces/trace-origin/) documentation. It is assumed that logs without a `sentry.origin` attribute are manually created by the user. + +```json +{ + "sentry.origin": "auto.db.graphql" +} +``` + Beyond these attributes, we are exploring if the SDK should also send OS, user, and device information automatically (via reading the appropriate contexts from the scope). Given this behaviour can easily be added as a new feature to the SDK, it does not have to be part of the initial SDK implementation until we make a finalized decision. ### SDK Integrations diff --git a/develop-docs/sdk/telemetry/traces/trace-origin.mdx b/develop-docs/sdk/telemetry/traces/trace-origin.mdx index 8f3a8d79cf8f2..8896aee4eeafb 100644 --- a/develop-docs/sdk/telemetry/traces/trace-origin.mdx +++ b/develop-docs/sdk/telemetry/traces/trace-origin.mdx @@ -2,11 +2,13 @@ title: Trace Origin --- -Trace origin indicates what created a trace or a span. Not all traces and spans contain enough information +Trace origin indicates what created a trace, span or log. Not all traces, spans or logs contain enough information to tell whether the user or what precisely in the SDK created it. Origin solves this problem. Origin can be sent with -the trace context or spans. -The SDKs should set this value automatically. It is not expected to be set manually by users. The value for origin should rarely change so that we can run proper analytics on them. +the trace context, spans, or logs. + +For logs and standalone spans, the origin should be set as the `sentry.origin` attribute key. +The SDKs should set this value automatically. It is not expected to be set manually by users. The value for origin should rarely change so that we can run proper analytics on them. The origin is of type `string` and consists of four parts: `...`. Only the first is mandatory. The parts build upon each other, meaning it is forbidden @@ -28,12 +30,10 @@ to skip one part. For example, you may send parts one and two but aren't allowed : _Optional_. Is the part of the integration of the SDK that created the trace or span. This is only useful when one integration creates multiple traces or spans, and you'd like to differentiate. Therefore, most of the time, this will be omitted. - All parts can only contain: -* Alphanumeric characters: `a-z` , `A-Z` , and `0-9`. -* Underscores: `_` - +- Alphanumeric characters: `a-z` , `A-Z` , and `0-9`. +- Underscores: `_` ### Examples @@ -53,7 +53,7 @@ All parts can only contain: - `auto.db.core_data` - `auto.db.graphql` -Origins of type `manual` can also have categories and integration names. For example, for the time to display feature, the user manually calls an API of the SDK, +Origins of type `manual` can also have categories and integration names. For example, for the time to display feature, the user manually calls an API of the SDK, creating a span. In this case, the SDK can tell what created the span, but the user did it manually. On the other hand, the SDK also automatically creates a span. In this case we end up with the following origins: @@ -63,5 +63,8 @@ automatically creates a span. In this case we end up with the following origins: ## See also: - Span Interface -- Trace Context +- + Trace Context + +- Logs Interface - Related [RFC](https://github.com/getsentry/rfcs/pull/73/); From c35358a64f6af3764cf51c4414198abe07c43777 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Mon, 7 Apr 2025 10:46:17 +0200 Subject: [PATCH 21/28] Make sentry.message.parameter singular matching otel conventions --- develop-docs/sdk/telemetry/logs.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/develop-docs/sdk/telemetry/logs.mdx b/develop-docs/sdk/telemetry/logs.mdx index 2b172c81d5007..43966728d0ee0 100644 --- a/develop-docs/sdk/telemetry/logs.mdx +++ b/develop-docs/sdk/telemetry/logs.mdx @@ -267,7 +267,7 @@ The internal SDK implementation is kept purposefully broad as we are still in ea By default the SDK should set the following attributes: 1. `sentry.message.template`: The parameterized template string -2. `sentry.message.parameters.X`: The parameters to the template string, where X is the number that represent the parameters position in the template string +2. `sentry.message.parameter.X`: The parameters to the template string, where X is the number that represent the parameters position in the template string 3. `sentry.environment`: The environment set in the SDK 4. `sentry.release`: The release set in the SDK 5. `sentry.trace.parent_span_id`: The span id of the span that was active when the log was collected. This should not be set if there was no active span. @@ -277,8 +277,8 @@ Example: ```json { "sentry.message.template": "Adding item %s for user %s", - "sentry.message.parameters.0": "item_id", - "sentry.message.parameters.1": "user_id", + "sentry.message.parameter.0": "item_id", + "sentry.message.parameter.1": "user_id", "sentry.environment": "production", "sentry.release": "1.0.0", "sentry.trace.parent_span_id": "b0e6f15b45c36b12" From f8a5fda5ab37ed16ca0065cbec0c5d7aaeaeda43 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Mon, 7 Apr 2025 11:08:39 +0200 Subject: [PATCH 22/28] clarify message parameter attribute and document sdk name/version attribute --- develop-docs/sdk/telemetry/logs.mdx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/develop-docs/sdk/telemetry/logs.mdx b/develop-docs/sdk/telemetry/logs.mdx index 43966728d0ee0..7c84cb6fd9953 100644 --- a/develop-docs/sdk/telemetry/logs.mdx +++ b/develop-docs/sdk/telemetry/logs.mdx @@ -267,10 +267,12 @@ The internal SDK implementation is kept purposefully broad as we are still in ea By default the SDK should set the following attributes: 1. `sentry.message.template`: The parameterized template string -2. `sentry.message.parameter.X`: The parameters to the template string, where X is the number that represent the parameters position in the template string +2. `sentry.message.parameter.X`: The parameters to the template string. X can either be the number that represent the parameter's position in the template string (`sentry.message.parameter.0`, `sentry.message.parameter.1`, etc) or the parameter's name (`sentry.message.parameter.item_id`, `sentry.message.parameter.user_id`, etc) 3. `sentry.environment`: The environment set in the SDK 4. `sentry.release`: The release set in the SDK 5. `sentry.trace.parent_span_id`: The span id of the span that was active when the log was collected. This should not be set if there was no active span. +6. `sentry.sdk.name`: The name of the SDK that sent the log +7. `sentry.sdk.version`: The version of the SDK that sent the log Example: @@ -281,7 +283,9 @@ Example: "sentry.message.parameter.1": "user_id", "sentry.environment": "production", "sentry.release": "1.0.0", - "sentry.trace.parent_span_id": "b0e6f15b45c36b12" + "sentry.trace.parent_span_id": "b0e6f15b45c36b12", + "sentry.sdk.name": "sentry.javascript.browser", + "sentry.sdk.version": "9.11.0" } ``` From 77d0b95c38aed8931a4e7ad6307c5bf24db87885 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Tue, 8 Apr 2025 11:14:55 +0200 Subject: [PATCH 23/28] feat: Document server.address --- develop-docs/sdk/telemetry/logs.mdx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/develop-docs/sdk/telemetry/logs.mdx b/develop-docs/sdk/telemetry/logs.mdx index 7c84cb6fd9953..e95ebaa8cea34 100644 --- a/develop-docs/sdk/telemetry/logs.mdx +++ b/develop-docs/sdk/telemetry/logs.mdx @@ -273,6 +273,7 @@ By default the SDK should set the following attributes: 5. `sentry.trace.parent_span_id`: The span id of the span that was active when the log was collected. This should not be set if there was no active span. 6. `sentry.sdk.name`: The name of the SDK that sent the log 7. `sentry.sdk.version`: The version of the SDK that sent the log +8. [BACKEND SDKS ONLY] `server.address`: The address of the server that sent the log. Equivalent to `server_name` we attach to errors and transactions. Example: @@ -284,8 +285,9 @@ Example: "sentry.environment": "production", "sentry.release": "1.0.0", "sentry.trace.parent_span_id": "b0e6f15b45c36b12", - "sentry.sdk.name": "sentry.javascript.browser", - "sentry.sdk.version": "9.11.0" + "sentry.sdk.name": "sentry.javascript.node", + "sentry.sdk.version": "9.11.0", + "server.address": "foo.example.com" } ``` From 4f667af4f80de223070036851d6734ce41e4560b Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Mon, 14 Apr 2025 09:24:02 -0400 Subject: [PATCH 24/28] clarify sampling controls --- develop-docs/sdk/telemetry/logs.mdx | 30 +++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/develop-docs/sdk/telemetry/logs.mdx b/develop-docs/sdk/telemetry/logs.mdx index e95ebaa8cea34..281815497a9a5 100644 --- a/develop-docs/sdk/telemetry/logs.mdx +++ b/develop-docs/sdk/telemetry/logs.mdx @@ -72,9 +72,7 @@ It consists of the following fields: `attributes` -: **Object, optional**. A dictionary of key-value pairs of arbitrary data attached to the log. Attributes must also declare the type of the value. The following types are supported: `string`, `boolean`, `integer`, `double`. - -Note: `type: "integer"` has string values because JSON only recognizes numbers as floating point values. +: **Object, optional**. A dictionary of key-value pairs of arbitrary data attached to the log. Attributes must also declare the type of the value. The following types are supported: `string`, `boolean`, `integer`, `double`. In the future arrays will be supported (`string[]`, `boolean[]`, `integer[]`, `double[]`). Example: @@ -86,7 +84,7 @@ Example: "type": "string" }, "db.response.returned_rows": { - "value": "123", + "value": 123, "type": "integer" }, "db_query_processing_time": { @@ -137,11 +135,13 @@ API wise the SDKs are required to expose logging methods which are to be defined ### Initialization Options -The SDKs need to expose the following two configuration options: +The SDKs must expose the following configuration options: + +- `enableLogs`/`enable_logs`: A boolean flag to control if log envelopes will be generated and sent to Sentry via the Sentry SDK's Logging APIs. If this flag is set to `false`, the SDK should not send logs to Sentry. Defaults to `false`. -- `enable_logs`/`enable_logs`: A boolean flag to control if log envelopes will be generated and sent to Sentry via the Sentry SDK's Logging APIs. If this flag is set to `false`, the SDK should not send logs to Sentry. Defaults to `false`. +- `beforeSendLog`/`before_send_log`: A function that takes a log object and returns a log object. This function is called before sending the log to Sentry. It can be used to modify the log object or to prevent the log from being sent to Sentry. This function is optional. -- `beforeSendLog`/`before_send_log`: A function that takes a log object and returns a log object. This function is called before sending the log to Sentry. It can be used to modify the log object or to prevent the log from being sent to Sentry. +- `logsSampleRate`/`logs_sample_rate`: A number between 0 and 1 that represents the probability that a log will be sent to Sentry. This sampling decision should be made before a log is processed by SDK to lower performance overhead. Defaults to 1.0. ```js Sentry.init({ @@ -155,10 +155,20 @@ Sentry.init({ return log; }, + + logsSampleRate: 1.0, }); ``` -At the current moment, logs are not sampled so no sampling configuration needs to be exposed. This may change in the future. +At the current moment logs sampling decisions are not propagated to downstream services, or be affected by the `tracesSampleRate` configuration option. In the future there might be more advanced client-side sampling and server-side sampling strategies, but this is not yet defined. + +While the logs functionality for an SDK is in an experimental state, SDKs should put these configuration options in an experimental namespace to avoid breaking changes. + +```js +Sentry.init({ + _experiments: { enableLogs: true }, +}); +``` ### Logger Module @@ -303,9 +313,9 @@ Beyond these attributes, we are exploring if the SDK should also send OS, user, ### SDK Integrations -SDKs should aim to have it so that console/logger integrations create logs as per the appropriate log level if `enableLogs` is set to true. Examples of this include JavaScript's `console` object and Pythons `logging` standard library. +SDKs should aim to have it so that console/logger integrations create logs as per the appropriate log level if `enableLogs`/`enable_logs` is set to true. Examples of this include JavaScript's `console` object and Pythons `logging` standard library. -If SDK authors feel the need, they can also introduce additional options to beyond `enableLogs` to gate this functionality. For example an option to control log appenders added via external config like with `Log4j` in the Java SDK. +If SDK authors feel the need, they can also introduce additional options to beyond `enableLogs`/`enable_logs` to gate this functionality. For example an option to control log appenders added via external config like with `Log4j` in the Java SDK. ## Appendix A: `otel_log` Envelope Item Payload From 4ce5d4d1cddf370b161e93e7eafb4bac8a0b28e6 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Mon, 14 Apr 2025 09:39:51 -0400 Subject: [PATCH 25/28] fix 404 link --- develop-docs/sdk/telemetry/logs.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/develop-docs/sdk/telemetry/logs.mdx b/develop-docs/sdk/telemetry/logs.mdx index 281815497a9a5..31c199d2eb314 100644 --- a/develop-docs/sdk/telemetry/logs.mdx +++ b/develop-docs/sdk/telemetry/logs.mdx @@ -301,7 +301,7 @@ Example: } ``` -If a log is generated by an SDK integration, the SDK should also set the `sentry.origin` attribute, as per the [Trace Origin](./traces/trace-origin/) documentation. It is assumed that logs without a `sentry.origin` attribute are manually created by the user. +If a log is generated by an SDK integration, the SDK should also set the `sentry.origin` attribute, as per the [Trace Origin](./traces/trace-origin) documentation. It is assumed that logs without a `sentry.origin` attribute are manually created by the user. ```json { From b3f8c652bb07c978edc0d8501a1c0ee877b983b0 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Wed, 16 Apr 2025 11:07:03 -0400 Subject: [PATCH 26/28] Add details about new log envelope item container --- .../sdk/data-model/envelope-items.mdx | 167 ++++++++++-------- 1 file changed, 96 insertions(+), 71 deletions(-) diff --git a/develop-docs/sdk/data-model/envelope-items.mdx b/develop-docs/sdk/data-model/envelope-items.mdx index 0f0a28a0ea8e1..6c5faf0479a0b 100644 --- a/develop-docs/sdk/data-model/envelope-items.mdx +++ b/develop-docs/sdk/data-model/envelope-items.mdx @@ -29,13 +29,13 @@ encoded in JSON. `event_id` : **UUID String, required.** Corresponds to the `event_id` field of the event - payload. Clients are required to generate an event identifier ahead of time - and set it at least in the Envelope headers. If the identifier mismatches - between the Envelope and payload, the Envelope header takes precedence. +payload. Clients are required to generate an event identifier ahead of time +and set it at least in the Envelope headers. If the identifier mismatches +between the Envelope and payload, the Envelope header takes precedence. **Additional Item Headers:** -*None* +_None_ ### Transaction @@ -52,14 +52,14 @@ in JSON. `event_id` : **UUID String, required.** Corresponds to the `event_id` field of the - transaction payload. Clients are required to generate an event identifier - ahead of time and set it at least in the Envelope headers. If the identifier - mismatches between the Envelope and payload, the Envelope header takes - precedence. +transaction payload. Clients are required to generate an event identifier +ahead of time and set it at least in the Envelope headers. If the identifier +mismatches between the Envelope and payload, the Envelope header takes +precedence. **Additional Item Headers:** -*None* +_None_ ### Attachment @@ -91,27 +91,27 @@ file. It is always associated to an event or transaction. `filename` -: **String, required.** The name of the uploaded file without a path component. +: **String, required.** The name of the uploaded file without a path component. `attachment_type` -: *String, optional.* The special type of this attachment. Possible values are: +: _String, optional._ The special type of this attachment. Possible values are: - - **`event.attachment` (default)**: A standard attachment without special - meaning. - - `event.minidump`: A minidump file that creates an error event and is - symbolicated. The file should start with the `MDMP` magic bytes. - - `event.applecrashreport`: An Apple crash report file that creates an error - event and is symbolicated. - - `unreal.context`: An XML file containing UE4 crash meta data. During event - ingestion, event contexts and extra fields are extracted from this file. - - `unreal.logs`: A plain-text log file obtained from UE4 crashes. During - event ingestion, the last logs are extracted into event breadcrumbs. - - `event.view_hierarchy`: An JSON file with a predefined structure, see [RFC #33](https://github.com/getsentry/rfcs/blob/main/text/0033-view-hierarchy.md). +- **`event.attachment` (default)**: A standard attachment without special + meaning. +- `event.minidump`: A minidump file that creates an error event and is + symbolicated. The file should start with the `MDMP` magic bytes. +- `event.applecrashreport`: An Apple crash report file that creates an error + event and is symbolicated. +- `unreal.context`: An XML file containing UE4 crash meta data. During event + ingestion, event contexts and extra fields are extracted from this file. +- `unreal.logs`: A plain-text log file obtained from UE4 crashes. During + event ingestion, the last logs are extracted into event breadcrumbs. +- `event.view_hierarchy`: An JSON file with a predefined structure, see [RFC #33](https://github.com/getsentry/rfcs/blob/main/text/0033-view-hierarchy.md). `content_type` -: *String, optional.* The content type of the attachment payload. Any [MIME type](https://www.iana.org/assignments/media-types/media-types.xhtml) may be used; the default is `application/octet-stream`. +: _String, optional._ The content type of the attachment payload. Any [MIME type](https://www.iana.org/assignments/media-types/media-types.xhtml) may be used; the default is `application/octet-stream`. ### Session @@ -124,11 +124,11 @@ details. **Constraints:** - This Item may occur multiple times per Envelope. -- Ingestion may limit the maximum number of Items per Envelope, see *Ingestion*. +- Ingestion may limit the maximum number of Items per Envelope, see _Ingestion_. **Additional Item Headers:** -*None* +_None_ ### Sessions @@ -140,11 +140,11 @@ details. **Constraints:** - This Item may occur multiple times per Envelope. -- Ingestion may limit the maximum number of Items per Envelope, see *Ingestion*. +- Ingestion may limit the maximum number of Items per Envelope, see _Ingestion_. **Additional Item Headers:** -*None* +_None_ ### Statsd (deprecated) @@ -156,11 +156,11 @@ details. **Constraints:** - This Item may occur multiple times per Envelope. -- Ingestion may limit the maximum number of Items per Envelope, see *Ingestion*. +- Ingestion may limit the maximum number of Items per Envelope, see _Ingestion_. **Additional Item Headers:** -*None* +_None_ ### Metric Meta (deprecated) @@ -173,17 +173,18 @@ details. **Constraints:** - This Item may occur multiple times per Envelope. -- Ingestion may limit the maximum number of Items per Envelope, see *Ingestion*. +- Ingestion may limit the maximum number of Items per Envelope, see _Ingestion_. **Additional Item Headers:** -*None* +_None_ ### User Feedback Item type `"feedback"`. This Item contains an [event payload](/sdk/data-model/event-payloads/) encoded in JSON, with an additional `feedback` context object. Example payload: + ```json { "event_id": "9ec79c33ec9942ab8353589fcb2e04dc", @@ -197,7 +198,7 @@ Example payload: "message": "I love session replay!", "url": "https://sentry.io/replays/", "associated_event_id": "32fd1995636d446385016e2747623e11", - "replay_id":"82840977e85b4ed3bc27f7b5b25cec15" + "replay_id": "82840977e85b4ed3bc27f7b5b25cec15" } } } @@ -215,26 +216,26 @@ feedback. The max length is **4096 characters**. `contact_email` -: *String, optional.* The email of the user who submitted the feedback. If excluded, Sentry attempts to fill this in with user context. Anonymous feedbacks (no name or email) are still accepted. +: _String, optional._ The email of the user who submitted the feedback. If excluded, Sentry attempts to fill this in with user context. Anonymous feedbacks (no name or email) are still accepted. `name` -: *String, optional.* The name of the user who submitted the feedback. If excluded, Sentry attempts to fill this in with user context. Anonymous feedbacks (no name or email) are still accepted. +: _String, optional._ The name of the user who submitted the feedback. If excluded, Sentry attempts to fill this in with user context. Anonymous feedbacks (no name or email) are still accepted. `url` -: *String, optional.* The URL of the webpage the user was on when submitting feedback. - This may be used to search for or set alerts on feedback. +: _String, optional._ The URL of the webpage the user was on when submitting feedback. +This may be used to search for or set alerts on feedback. `associated_event_id` -: *UUID String, optional.* The identifier of an error event in the same project. - Use this to explicitly link a related error in the feedback UI. +: _UUID String, optional._ The identifier of an error event in the same project. +Use this to explicitly link a related error in the feedback UI. `replay_id` -: *UUID String, optional.* The identifier of a related Session Replay in the same - project. Sentry uses this ID to render a Replay clip in the feedback UI. +: _UUID String, optional._ The identifier of a related Session Replay in the same +project. Sentry uses this ID to render a Replay clip in the feedback UI. **Attaching Screenshots:** @@ -253,10 +254,10 @@ Envelope. `event_id` : **UUID String, required.** Corresponds to the `event_id` field of the event - payload. **It is not equal to the `associated_event_id`** field in the feedback - context. Clients are required to generate an event identifier ahead of time - and set it at least in the Envelope headers. If the identifier mismatches - between the Envelope and payload, the Envelope header takes precedence. +payload. **It is not equal to the `associated_event_id`** field in the feedback +context. Clients are required to generate an event identifier ahead of time +and set it at least in the Envelope headers. If the identifier mismatches +between the Envelope and payload, the Envelope header takes precedence. ### User Report - Deprecated @@ -265,6 +266,7 @@ Item type `"user_report"`. This is an older, deprecated way of submitting user f This item works by associating user information and comments with an event. If both the item and its associated event are accepted, we convert it to a user feedback. The item contains a JSON payload like this: + ```json {"event_id":"9ec79c33ec9942ab8353589fcb2e04dc","email":"john@example.com","name":"John Me","comments":"It broke."}\n ``` @@ -278,15 +280,15 @@ an error. `email` -: *String, recommended.* The email of the user. +: _String, recommended._ The email of the user. `name` -: *String, recommended.* The name of the user. +: _String, recommended._ The name of the user. `comments` -: *String, recommended.* Comments of the user about what happened. The max length is **4096 characters**. +: _String, recommended._ Comments of the user about what happened. The max length is **4096 characters**. **Constraints:** @@ -303,12 +305,12 @@ an error. `event_id` : **UUID String, required.** Corresponds to the `event_id` field of the payload. - If the identifier mismatches between the Envelope and payload, the Envelope - header takes precedence. +If the identifier mismatches between the Envelope and payload, the Envelope +header takes precedence. **Additional Item Headers:** -*None* +_None_ ### Client Report @@ -324,11 +326,11 @@ details. **Envelope Headers:** -*None* +_None_ **Additional Item Headers:** -*None* +_None_ ### Replay Event @@ -344,15 +346,15 @@ details. **Envelope Headers:** -*None* +_None_ **Additional Item Headers:** -*None* +_None_ ### Replay Recording -Item type `"replay_recording"` contains a replay recording payload encoded in JSON *or* a gzipped JSON. +Item type `"replay_recording"` contains a replay recording payload encoded in JSON _or_ a gzipped JSON. See the replays documentation for the payload details. @@ -364,7 +366,7 @@ details. **Envelope Headers:** -*None* +_None_ **Additional Item Headers:** @@ -384,11 +386,11 @@ in JSON. **Envelope Headers:** -*None* +_None_ **Additional Item Headers:** -*None* +_None_ ### Profile Chunk @@ -397,15 +399,15 @@ in JSON. **Constraints:** -*None* +_None_ **Envelope Headers:** -*None* +_None_ **Additional Item Headers:** -*None* +_None_ ### Check-Ins @@ -421,30 +423,53 @@ details. **Envelope Headers:** -*None* +_None_ **Additional Item Headers:** -*None* +_None_ + +### Log + +Item type `"log"` contains an array of log payloads encoded as JSON. This allows for multiple log payloads to be sent in a single envelope item. -### Logs +Only a single log item is allowed per envelope. The `item_count` field in the envelope item header must match the amount of logs sent, it's not optional. A `content_type` field in the envelope item header must be set to `application/vnd.sentry.items.log+json`. -Item type `"log"` contains a logs payload encoded as JSON. Multiple log envelope items can be sent in a single envelope. +It's okay to mix logs from different traces into the same log envelope item, but if you do, you MUST not attach a DSC (dynamic sampling context) to the envelope header. See the Logs documentation for the payload details. +Example: + +```json +{ + "type": "log", + "item_count": 5, + "content_type": "application/vnd.sentry.items.log+json" +} +{ + "items": [{..log..}, {..log..}, {..log..}, {..log..}, {..log..}] +} +``` + **Constraints:** -*None* +_None_ **Envelope Headers:** -*None* +_None_ **Additional Item Headers:** -*None* +`item_count` + +: **integer, required.** The number of log items in the envelope. + +`content_type` + +: **string, required.** The content type of the log items. Must be `application/vnd.sentry.items.log+json`. ### Otel Logs @@ -455,15 +480,15 @@ details. **Constraints:** -*None* +_None_ **Envelope Headers:** -*None* +_None_ **Additional Item Headers:** -*None* +_None_ ### Reserved Types From f5fc96f1d1b11cc055b685ae72f2021a7559714f Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Tue, 22 Apr 2025 09:46:14 -0400 Subject: [PATCH 27/28] move appendix into expandable --- develop-docs/sdk/data-model/envelope-items.mdx | 4 ++-- develop-docs/sdk/telemetry/logs.mdx | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/develop-docs/sdk/data-model/envelope-items.mdx b/develop-docs/sdk/data-model/envelope-items.mdx index 6c5faf0479a0b..7b457e14d60fc 100644 --- a/develop-docs/sdk/data-model/envelope-items.mdx +++ b/develop-docs/sdk/data-model/envelope-items.mdx @@ -465,11 +465,11 @@ _None_ `item_count` -: **integer, required.** The number of log items in the envelope. +: **integer, required.** The number of log entries in the envelope. `content_type` -: **string, required.** The content type of the log items. Must be `application/vnd.sentry.items.log+json`. +: **string, required.** The content type of the log entries. Must be `application/vnd.sentry.items.log+json`. ### Otel Logs diff --git a/develop-docs/sdk/telemetry/logs.mdx b/develop-docs/sdk/telemetry/logs.mdx index 31c199d2eb314..a2df54006e82a 100644 --- a/develop-docs/sdk/telemetry/logs.mdx +++ b/develop-docs/sdk/telemetry/logs.mdx @@ -319,6 +319,8 @@ If SDK authors feel the need, they can also introduce additional options to beyo ## Appendix A: `otel_log` Envelope Item Payload + + The `otel_log` envelope item payload is a JSON object that represents an OpenTelemetry Log. Multiple `otel_log` envelope items can be sent in a single envelope. This is implementation of the [OpenTelemetry Log Data Model](https://opentelemetry.io/docs/specs/otel/logs/data-model/). ```json @@ -411,3 +413,5 @@ Example: `time_unix_nano` : **String, optional**. The time the log was created in Unix nanoseconds. If not set, the SDK should set this to the current time. + + From 625160337168976a1f2400b00beead44669fe1fc Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Tue, 22 Apr 2025 10:43:41 -0400 Subject: [PATCH 28/28] fix 404 to trace origin --- develop-docs/sdk/telemetry/logs.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/develop-docs/sdk/telemetry/logs.mdx b/develop-docs/sdk/telemetry/logs.mdx index a2df54006e82a..616e5345f7780 100644 --- a/develop-docs/sdk/telemetry/logs.mdx +++ b/develop-docs/sdk/telemetry/logs.mdx @@ -301,7 +301,7 @@ Example: } ``` -If a log is generated by an SDK integration, the SDK should also set the `sentry.origin` attribute, as per the [Trace Origin](./traces/trace-origin) documentation. It is assumed that logs without a `sentry.origin` attribute are manually created by the user. +If a log is generated by an SDK integration, the SDK should also set the `sentry.origin` attribute, as per the [Trace Origin](/sdk/telemetry/traces/trace-origin/) documentation. It is assumed that logs without a `sentry.origin` attribute are manually created by the user. ```json {