feat(logs): initial work on develop docs for sdk logging api - #12920

Merged
AbhiPrasad merged 32 commits into
masterfrom
abhi-logs-sdk-developer-documentation
Apr 22, 2025
Merged

feat(logs): initial work on develop docs for sdk logging api#12920
AbhiPrasad merged 32 commits into
masterfrom
abhi-logs-sdk-developer-documentation

Conversation

@AbhiPrasad

@AbhiPrasadAbhiPrasad commented Mar 4, 2025

Copy link
Copy Markdown
Contributor

resolves#12870

Sentry is exploring an application logging product! More details here in our internal notion: https://www.notion.so/sentry/PRFAQ-Application-Logging-1258b10e4b5d80ea8e98e8ec5505542c.

To get the ball rolling, I'm helping push forward the spec in the SDK. This was initially in Notion (https://www.notion.so/sentry/Logs-in-the-SDK-1a48b10e4b5d80b1827fe14d9fd0236b#1a58b10e4b5d80019d2eef6d84213d4a), but now we're moving it to develop so that we can work more in the open.

This PR documents:

  1. The idealized public api for logs
  2. The idealized sdk options for logs
  3. The otel log envelope format
  4. The recommended internal sdk behavior for logs

You'll notice only the otel_log envelope item is documented. This is what we used for the first alpha release of the SDK, but we'll be moving the SDKs to use the log envelope item instead. Until the logenvelope item protocol is finalized we are avoiding documenting in develop, but we marked it as TODO in the necessary sections. No longer applies log envelope item has been documented.

Rendered Preview:

@AbhiPrasadAbhiPrasad self-assigned this Mar 4, 2025
@vercel

vercelBot commented Mar 4, 2025

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for Git ↗︎

NameStatusPreviewCommentsUpdated (UTC)
develop-docs✅ Ready (Inspect)Visit Preview💬 Add feedbackApr 22, 2025 2:51pm
2 Skipped Deployments
NameStatusPreviewCommentsUpdated (UTC)
changelog⬜️ Ignored (Inspect)Visit PreviewApr 22, 2025 2:51pm
sentry-docs⬜️ Ignored (Inspect)Visit PreviewApr 22, 2025 2:51pm

@AbhiPrasadAbhiPrasad changed the title [WIP] feat(logs): intial work on develop docs for sdk logging apifeat(logs): intial work on develop docs for sdk logging apiMar 5, 2025
Comment threaddevelop-docs/sdk/data-model/envelope-items.mdx Outdated
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Co-authored-by: Alex Krawiec <alex.krawiec@sentry.io>
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Co-authored-by: Lorenzo Cian <lorenzo.cian@sentry.io>
Comment threaddevelop-docs/sdk/telemetry/logs.mdx
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Comment on lines +81 to +86
{
"key": "string_item",
"value": {
"stringValue": "value"
}
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I find this format quite clunky, is this how OTel does things? If we have some leeway here I think the following would already go a long way towards making this easier to work with:

  1. removing the extra nesting; i.e., not having "value" be a dictionary but rather the flat value
  2. instead of having different names for the key depending on the type, moving the type into its own key

So basically the above would become this:

Suggested change
{
"key": "string_item",
"value": {
"stringValue": "value"
}
},
{
"key": "string_item",
"value": "value",
"type": "string",
},

I'd especially like to do 2. since in Python it otherwise leads to some non-idiomatic code where instead of just accessing the value by key, you have to pop() from the dict instead. It's not a huge deal but I had to work with dicts like this and it felt very clunky.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nevermind, this is the format for otel_log so I guess we can't be creative here. :) But maybe we can come up with a nicer format for logs once we get to defining that.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I was also thinking that the format is a bit verbose. But as this is just the otel logs data model https://opentelemetry.io/docs/specs/otel/logs/data-model/ it is fine.

For the logs type I think we should also be as close to potel as possible. As this is an internal format and the user will probably never see this, it does not matter if it is a bit verbose.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we may be heading towards using AnyValue proto (the value type you're seeing here, from OTel) in our RPCs, in which case I think we may not want to be creative at all for the transport protocol for sdks since AnyValue will be used essentially everywhere in our product from ingest to rpc to frontend.

It may make more sense for the sdks to offer idiomatic apis that convert into our protocol, especially since the idioms differ anyway (eg. stringValue is fine in js since it's usually camelCase).

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

We've improved this with logs pageload, see 3ff6e56

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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should this be sentry.server.address?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

We're using the OTEL conventions directly here, so I feel fine with setting it this way. There's nothing specific about this attribute to sentry.

k-fish added a commit to getsentry/relay that referenced this pull request Apr 11, 2025
### Summary
Now that we've mostly finalized the logs protocol with sdks (see
[develop doc for more
info](getsentry/sentry-docs#12920)), we want to
update Relay to allow the 'log' item type to be sent in this format.
SDK's will likely primarily use the `log` ItemType instead of `otel_log`
since we don't need to change timestamp conventions, can send a
simplified `level` (see `OurLogLevel` added in this PR).
#### Schema changes
We've deprecated some fields in the protocol that only exist for OTEL:
- `severity_number` and `severity_text`, we're coercing these to
`level`, but we're keeping the original severity text and number as
attributes as OTel allows custom severity text.
- `observed_timestamp_nanos` is always set by relay regardless of what
is sent because Relay is the 'collector'. We have to leave this as an
attribute as well since it's being used by the existing consumer for
origin timestamp.
- `timestamp_nanos` becomes `timestamp: Timestamp`
- `trace_flags`, this is unused, and the consumer doesn't even store it
in the table. Will decide what to do with this later.
#### Future work
- The `ourlog_merge_otel` function can be trimmed down since we won't
need to fill in deprecated fields to send the same data to the kafka
consumer.
- We may need to transform the `OurLog` protocol from json received from
sdks to a generic EAP "trace items" kafka message that is essentially a
couple fields (eg. traceid) + a KVMap for `attributes`.
---------
Co-authored-by: Michi Hoffmann <cleptric@users.noreply.github.com>
Co-authored-by: David Herberth <david.herberth@sentry.io>

@cleptriccleptric left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Weeee :shipit:

*None*
`item_count`

: **integer, required.** The number of log items in the envelope.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
: **integer, required.** The number of log items in the envelope.
: **integer, required.** The number of log entries in the item.

It's just scoped to the item, unfortunately naming clashes here "log item" and "envelope item"

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Naming is hard - good catch, will fix.

@AbhiPrasad

Copy link
Copy Markdown
ContributorAuthor

This is ready to merge, will do so as soon as CI passes.

The only thing major TODO to iterate on this the default attributes section. Because this still has some open Q, I'm going to tackle this in a follow up.

@codecov

codecovBot commented Apr 22, 2025

Copy link
Copy Markdown

Bundle Report

Changes will increase total bundle size by 135 bytes (0.0%) ⬆️. This is within the configured threshold ✅

Detailed changes
Bundle nameSizeChange
sentry-docs-server-cjs11.14MB141 bytes (0.0%) ⬆️
sentry-docs-client-array-push9.47MB-6 bytes (-0.0%) ⬇️

Affected Assets, Files, and Routes:

view changes for bundle: sentry-docs-server-cjs

Assets Changed:

Asset NameSize ChangeTotal SizeChange (%)
1729.js-3 bytes1.75MB-0.0%
../instrumentation.js-3 bytes1.08MB-0.0%
9523.js-3 bytes1.05MB-0.0%
../app/[[...path]]/page.js.nft.json50 bytes388.48kB0.01%
../app/platform-redirect/page.js.nft.json50 bytes388.39kB0.01%
../app/sitemap.xml/route.js.nft.json50 bytes386.36kB0.01%
view changes for bundle: sentry-docs-client-array-push

Assets Changed:

Asset NameSize ChangeTotal SizeChange (%)
static/chunks/pages/_app-*.js-3 bytes868.7kB-0.0%
static/chunks/8165-*.js-3 bytes410.1kB-0.0%
server/middleware-*.js5.55kB6.55kB555.3% ⚠️
server/middleware-*.js-5.55kB1.0kB-84.74%
static/ys4-*.js(New)578 bytes578 bytes100.0% 🚀
static/ys4-*.js(New)77 bytes77 bytes100.0% 🚀
static/Yd0cqjRC-*.js(Deleted)-578 bytes0 bytes-100.0% 🗑️
static/Yd0cqjRC-*.js(Deleted)-77 bytes0 bytes-100.0% 🗑️

@AbhiPrasad
AbhiPrasad merged commit 385e6e6 into masterApr 22, 2025
@AbhiPrasad
AbhiPrasad deleted the abhi-logs-sdk-developer-documentation branch April 22, 2025 14:51
@github-actionsgithub-actionsBot locked and limited conversation to collaborators May 8, 2025
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Logs Section to Develop Docs

10 participants

@AbhiPrasad@antonpirker@Dav1dde@philipphofmann@romtsn@k-fish@cleptric@lcian@coolguyzone@sentrivana
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat(logs): initial work on develop docs for sdk logging api - #12920

Merged
AbhiPrasad merged 32 commits into
masterfrom
abhi-logs-sdk-developer-documentation
Apr 22, 2025
Merged

feat(logs): initial work on develop docs for sdk logging api#12920
AbhiPrasad merged 32 commits into
masterfrom
abhi-logs-sdk-developer-documentation

Conversation

@AbhiPrasad

@AbhiPrasadAbhiPrasad commented Mar 4, 2025

Copy link
Copy Markdown
Contributor

resolves#12870

Sentry is exploring an application logging product! More details here in our internal notion: https://www.notion.so/sentry/PRFAQ-Application-Logging-1258b10e4b5d80ea8e98e8ec5505542c.

To get the ball rolling, I'm helping push forward the spec in the SDK. This was initially in Notion (https://www.notion.so/sentry/Logs-in-the-SDK-1a48b10e4b5d80b1827fe14d9fd0236b#1a58b10e4b5d80019d2eef6d84213d4a), but now we're moving it to develop so that we can work more in the open.

This PR documents:

  1. The idealized public api for logs
  2. The idealized sdk options for logs
  3. The otel log envelope format
  4. The recommended internal sdk behavior for logs

You'll notice only the otel_log envelope item is documented. This is what we used for the first alpha release of the SDK, but we'll be moving the SDKs to use the log envelope item instead. Until the logenvelope item protocol is finalized we are avoiding documenting in develop, but we marked it as TODO in the necessary sections. No longer applies log envelope item has been documented.

Rendered Preview:

@AbhiPrasadAbhiPrasad self-assigned this Mar 4, 2025
@vercel

vercelBot commented Mar 4, 2025

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for Git ↗︎

NameStatusPreviewCommentsUpdated (UTC)
develop-docs✅ Ready (Inspect)Visit Preview💬 Add feedbackApr 22, 2025 2:51pm
2 Skipped Deployments
NameStatusPreviewCommentsUpdated (UTC)
changelog⬜️ Ignored (Inspect)Visit PreviewApr 22, 2025 2:51pm
sentry-docs⬜️ Ignored (Inspect)Visit PreviewApr 22, 2025 2:51pm

@AbhiPrasadAbhiPrasad changed the title [WIP] feat(logs): intial work on develop docs for sdk logging apifeat(logs): intial work on develop docs for sdk logging apiMar 5, 2025
Comment threaddevelop-docs/sdk/data-model/envelope-items.mdx Outdated
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Co-authored-by: Alex Krawiec <alex.krawiec@sentry.io>
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Co-authored-by: Lorenzo Cian <lorenzo.cian@sentry.io>
Comment threaddevelop-docs/sdk/telemetry/logs.mdx
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Comment on lines +81 to +86
{
"key": "string_item",
"value": {
"stringValue": "value"
}
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I find this format quite clunky, is this how OTel does things? If we have some leeway here I think the following would already go a long way towards making this easier to work with:

  1. removing the extra nesting; i.e., not having "value" be a dictionary but rather the flat value
  2. instead of having different names for the key depending on the type, moving the type into its own key

So basically the above would become this:

Suggested change
{
"key": "string_item",
"value": {
"stringValue": "value"
}
},
{
"key": "string_item",
"value": "value",
"type": "string",
},

I'd especially like to do 2. since in Python it otherwise leads to some non-idiomatic code where instead of just accessing the value by key, you have to pop() from the dict instead. It's not a huge deal but I had to work with dicts like this and it felt very clunky.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nevermind, this is the format for otel_log so I guess we can't be creative here. :) But maybe we can come up with a nicer format for logs once we get to defining that.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I was also thinking that the format is a bit verbose. But as this is just the otel logs data model https://opentelemetry.io/docs/specs/otel/logs/data-model/ it is fine.

For the logs type I think we should also be as close to potel as possible. As this is an internal format and the user will probably never see this, it does not matter if it is a bit verbose.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we may be heading towards using AnyValue proto (the value type you're seeing here, from OTel) in our RPCs, in which case I think we may not want to be creative at all for the transport protocol for sdks since AnyValue will be used essentially everywhere in our product from ingest to rpc to frontend.

It may make more sense for the sdks to offer idiomatic apis that convert into our protocol, especially since the idioms differ anyway (eg. stringValue is fine in js since it's usually camelCase).

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

We've improved this with logs pageload, see 3ff6e56

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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should this be sentry.server.address?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

We're using the OTEL conventions directly here, so I feel fine with setting it this way. There's nothing specific about this attribute to sentry.

k-fish added a commit to getsentry/relay that referenced this pull request Apr 11, 2025
### Summary
Now that we've mostly finalized the logs protocol with sdks (see
[develop doc for more
info](getsentry/sentry-docs#12920)), we want to
update Relay to allow the 'log' item type to be sent in this format.
SDK's will likely primarily use the `log` ItemType instead of `otel_log`
since we don't need to change timestamp conventions, can send a
simplified `level` (see `OurLogLevel` added in this PR).
#### Schema changes
We've deprecated some fields in the protocol that only exist for OTEL:
- `severity_number` and `severity_text`, we're coercing these to
`level`, but we're keeping the original severity text and number as
attributes as OTel allows custom severity text.
- `observed_timestamp_nanos` is always set by relay regardless of what
is sent because Relay is the 'collector'. We have to leave this as an
attribute as well since it's being used by the existing consumer for
origin timestamp.
- `timestamp_nanos` becomes `timestamp: Timestamp`
- `trace_flags`, this is unused, and the consumer doesn't even store it
in the table. Will decide what to do with this later.
#### Future work
- The `ourlog_merge_otel` function can be trimmed down since we won't
need to fill in deprecated fields to send the same data to the kafka
consumer.
- We may need to transform the `OurLog` protocol from json received from
sdks to a generic EAP "trace items" kafka message that is essentially a
couple fields (eg. traceid) + a KVMap for `attributes`.
---------
Co-authored-by: Michi Hoffmann <cleptric@users.noreply.github.com>
Co-authored-by: David Herberth <david.herberth@sentry.io>

@cleptriccleptric left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Weeee :shipit:

*None*
`item_count`

: **integer, required.** The number of log items in the envelope.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
: **integer, required.** The number of log items in the envelope.
: **integer, required.** The number of log entries in the item.

It's just scoped to the item, unfortunately naming clashes here "log item" and "envelope item"

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Naming is hard - good catch, will fix.

@AbhiPrasad

Copy link
Copy Markdown
ContributorAuthor

This is ready to merge, will do so as soon as CI passes.

The only thing major TODO to iterate on this the default attributes section. Because this still has some open Q, I'm going to tackle this in a follow up.

@codecov

codecovBot commented Apr 22, 2025

Copy link
Copy Markdown

Bundle Report

Changes will increase total bundle size by 135 bytes (0.0%) ⬆️. This is within the configured threshold ✅

Detailed changes
Bundle nameSizeChange
sentry-docs-server-cjs11.14MB141 bytes (0.0%) ⬆️
sentry-docs-client-array-push9.47MB-6 bytes (-0.0%) ⬇️

Affected Assets, Files, and Routes:

view changes for bundle: sentry-docs-server-cjs

Assets Changed:

Asset NameSize ChangeTotal SizeChange (%)
1729.js-3 bytes1.75MB-0.0%
../instrumentation.js-3 bytes1.08MB-0.0%
9523.js-3 bytes1.05MB-0.0%
../app/[[...path]]/page.js.nft.json50 bytes388.48kB0.01%
../app/platform-redirect/page.js.nft.json50 bytes388.39kB0.01%
../app/sitemap.xml/route.js.nft.json50 bytes386.36kB0.01%
view changes for bundle: sentry-docs-client-array-push

Assets Changed:

Asset NameSize ChangeTotal SizeChange (%)
static/chunks/pages/_app-*.js-3 bytes868.7kB-0.0%
static/chunks/8165-*.js-3 bytes410.1kB-0.0%
server/middleware-*.js5.55kB6.55kB555.3% ⚠️
server/middleware-*.js-5.55kB1.0kB-84.74%
static/ys4-*.js(New)578 bytes578 bytes100.0% 🚀
static/ys4-*.js(New)77 bytes77 bytes100.0% 🚀
static/Yd0cqjRC-*.js(Deleted)-578 bytes0 bytes-100.0% 🗑️
static/Yd0cqjRC-*.js(Deleted)-77 bytes0 bytes-100.0% 🗑️

@AbhiPrasad
AbhiPrasad merged commit 385e6e6 into masterApr 22, 2025
@AbhiPrasad
AbhiPrasad deleted the abhi-logs-sdk-developer-documentation branch April 22, 2025 14:51
@github-actionsgithub-actionsBot locked and limited conversation to collaborators May 8, 2025
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Logs Section to Develop Docs

10 participants

@AbhiPrasad@antonpirker@Dav1dde@philipphofmann@romtsn@k-fish@cleptric@lcian@coolguyzone@sentrivana
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(logs): initial work on develop docs for sdk logging api - #12920

Merged
AbhiPrasad merged 32 commits into
masterfrom
abhi-logs-sdk-developer-documentation
Apr 22, 2025
Merged

feat(logs): initial work on develop docs for sdk logging api#12920
AbhiPrasad merged 32 commits into
masterfrom
abhi-logs-sdk-developer-documentation

Conversation

@AbhiPrasad

@AbhiPrasadAbhiPrasad commented Mar 4, 2025

Copy link
Copy Markdown
Contributor

resolves#12870

Sentry is exploring an application logging product! More details here in our internal notion: https://www.notion.so/sentry/PRFAQ-Application-Logging-1258b10e4b5d80ea8e98e8ec5505542c.

To get the ball rolling, I'm helping push forward the spec in the SDK. This was initially in Notion (https://www.notion.so/sentry/Logs-in-the-SDK-1a48b10e4b5d80b1827fe14d9fd0236b#1a58b10e4b5d80019d2eef6d84213d4a), but now we're moving it to develop so that we can work more in the open.

This PR documents:

  1. The idealized public api for logs
  2. The idealized sdk options for logs
  3. The otel log envelope format
  4. The recommended internal sdk behavior for logs

You'll notice only the otel_log envelope item is documented. This is what we used for the first alpha release of the SDK, but we'll be moving the SDKs to use the log envelope item instead. Until the logenvelope item protocol is finalized we are avoiding documenting in develop, but we marked it as TODO in the necessary sections. No longer applies log envelope item has been documented.

Rendered Preview:

@AbhiPrasadAbhiPrasad self-assigned this Mar 4, 2025
@vercel

vercelBot commented Mar 4, 2025

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for Git ↗︎

NameStatusPreviewCommentsUpdated (UTC)
develop-docs✅ Ready (Inspect)Visit Preview💬 Add feedbackApr 22, 2025 2:51pm
2 Skipped Deployments
NameStatusPreviewCommentsUpdated (UTC)
changelog⬜️ Ignored (Inspect)Visit PreviewApr 22, 2025 2:51pm
sentry-docs⬜️ Ignored (Inspect)Visit PreviewApr 22, 2025 2:51pm

@AbhiPrasadAbhiPrasad changed the title [WIP] feat(logs): intial work on develop docs for sdk logging apifeat(logs): intial work on develop docs for sdk logging apiMar 5, 2025
Comment threaddevelop-docs/sdk/data-model/envelope-items.mdx Outdated
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Co-authored-by: Alex Krawiec <alex.krawiec@sentry.io>
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Co-authored-by: Lorenzo Cian <lorenzo.cian@sentry.io>
Comment threaddevelop-docs/sdk/telemetry/logs.mdx
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Comment on lines +81 to +86
{
"key": "string_item",
"value": {
"stringValue": "value"
}
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I find this format quite clunky, is this how OTel does things? If we have some leeway here I think the following would already go a long way towards making this easier to work with:

  1. removing the extra nesting; i.e., not having "value" be a dictionary but rather the flat value
  2. instead of having different names for the key depending on the type, moving the type into its own key

So basically the above would become this:

Suggested change
{
"key": "string_item",
"value": {
"stringValue": "value"
}
},
{
"key": "string_item",
"value": "value",
"type": "string",
},

I'd especially like to do 2. since in Python it otherwise leads to some non-idiomatic code where instead of just accessing the value by key, you have to pop() from the dict instead. It's not a huge deal but I had to work with dicts like this and it felt very clunky.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nevermind, this is the format for otel_log so I guess we can't be creative here. :) But maybe we can come up with a nicer format for logs once we get to defining that.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I was also thinking that the format is a bit verbose. But as this is just the otel logs data model https://opentelemetry.io/docs/specs/otel/logs/data-model/ it is fine.

For the logs type I think we should also be as close to potel as possible. As this is an internal format and the user will probably never see this, it does not matter if it is a bit verbose.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we may be heading towards using AnyValue proto (the value type you're seeing here, from OTel) in our RPCs, in which case I think we may not want to be creative at all for the transport protocol for sdks since AnyValue will be used essentially everywhere in our product from ingest to rpc to frontend.

It may make more sense for the sdks to offer idiomatic apis that convert into our protocol, especially since the idioms differ anyway (eg. stringValue is fine in js since it's usually camelCase).

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

We've improved this with logs pageload, see 3ff6e56

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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should this be sentry.server.address?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

We're using the OTEL conventions directly here, so I feel fine with setting it this way. There's nothing specific about this attribute to sentry.

k-fish added a commit to getsentry/relay that referenced this pull request Apr 11, 2025
### Summary
Now that we've mostly finalized the logs protocol with sdks (see
[develop doc for more
info](getsentry/sentry-docs#12920)), we want to
update Relay to allow the 'log' item type to be sent in this format.
SDK's will likely primarily use the `log` ItemType instead of `otel_log`
since we don't need to change timestamp conventions, can send a
simplified `level` (see `OurLogLevel` added in this PR).
#### Schema changes
We've deprecated some fields in the protocol that only exist for OTEL:
- `severity_number` and `severity_text`, we're coercing these to
`level`, but we're keeping the original severity text and number as
attributes as OTel allows custom severity text.
- `observed_timestamp_nanos` is always set by relay regardless of what
is sent because Relay is the 'collector'. We have to leave this as an
attribute as well since it's being used by the existing consumer for
origin timestamp.
- `timestamp_nanos` becomes `timestamp: Timestamp`
- `trace_flags`, this is unused, and the consumer doesn't even store it
in the table. Will decide what to do with this later.
#### Future work
- The `ourlog_merge_otel` function can be trimmed down since we won't
need to fill in deprecated fields to send the same data to the kafka
consumer.
- We may need to transform the `OurLog` protocol from json received from
sdks to a generic EAP "trace items" kafka message that is essentially a
couple fields (eg. traceid) + a KVMap for `attributes`.
---------
Co-authored-by: Michi Hoffmann <cleptric@users.noreply.github.com>
Co-authored-by: David Herberth <david.herberth@sentry.io>

@cleptriccleptric left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Weeee :shipit:

*None*
`item_count`

: **integer, required.** The number of log items in the envelope.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
: **integer, required.** The number of log items in the envelope.
: **integer, required.** The number of log entries in the item.

It's just scoped to the item, unfortunately naming clashes here "log item" and "envelope item"

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Naming is hard - good catch, will fix.

@AbhiPrasad

Copy link
Copy Markdown
ContributorAuthor

This is ready to merge, will do so as soon as CI passes.

The only thing major TODO to iterate on this the default attributes section. Because this still has some open Q, I'm going to tackle this in a follow up.

@codecov

codecovBot commented Apr 22, 2025

Copy link
Copy Markdown

Bundle Report

Changes will increase total bundle size by 135 bytes (0.0%) ⬆️. This is within the configured threshold ✅

Detailed changes
Bundle nameSizeChange
sentry-docs-server-cjs11.14MB141 bytes (0.0%) ⬆️
sentry-docs-client-array-push9.47MB-6 bytes (-0.0%) ⬇️

Affected Assets, Files, and Routes:

view changes for bundle: sentry-docs-server-cjs

Assets Changed:

Asset NameSize ChangeTotal SizeChange (%)
1729.js-3 bytes1.75MB-0.0%
../instrumentation.js-3 bytes1.08MB-0.0%
9523.js-3 bytes1.05MB-0.0%
../app/[[...path]]/page.js.nft.json50 bytes388.48kB0.01%
../app/platform-redirect/page.js.nft.json50 bytes388.39kB0.01%
../app/sitemap.xml/route.js.nft.json50 bytes386.36kB0.01%
view changes for bundle: sentry-docs-client-array-push

Assets Changed:

Asset NameSize ChangeTotal SizeChange (%)
static/chunks/pages/_app-*.js-3 bytes868.7kB-0.0%
static/chunks/8165-*.js-3 bytes410.1kB-0.0%
server/middleware-*.js5.55kB6.55kB555.3% ⚠️
server/middleware-*.js-5.55kB1.0kB-84.74%
static/ys4-*.js(New)578 bytes578 bytes100.0% 🚀
static/ys4-*.js(New)77 bytes77 bytes100.0% 🚀
static/Yd0cqjRC-*.js(Deleted)-578 bytes0 bytes-100.0% 🗑️
static/Yd0cqjRC-*.js(Deleted)-77 bytes0 bytes-100.0% 🗑️

@AbhiPrasad
AbhiPrasad merged commit 385e6e6 into masterApr 22, 2025
@AbhiPrasad
AbhiPrasad deleted the abhi-logs-sdk-developer-documentation branch April 22, 2025 14:51
@github-actionsgithub-actionsBot locked and limited conversation to collaborators May 8, 2025
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Logs Section to Develop Docs

10 participants

@AbhiPrasad@antonpirker@Dav1dde@philipphofmann@romtsn@k-fish@cleptric@lcian@coolguyzone@sentrivana
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(logs): initial work on develop docs for sdk logging api - #12920

Merged
AbhiPrasad merged 32 commits into
masterfrom
abhi-logs-sdk-developer-documentation
Apr 22, 2025
Merged

feat(logs): initial work on develop docs for sdk logging api#12920
AbhiPrasad merged 32 commits into
masterfrom
abhi-logs-sdk-developer-documentation

Conversation

@AbhiPrasad

@AbhiPrasadAbhiPrasad commented Mar 4, 2025

Copy link
Copy Markdown
Contributor

resolves#12870

Sentry is exploring an application logging product! More details here in our internal notion: https://www.notion.so/sentry/PRFAQ-Application-Logging-1258b10e4b5d80ea8e98e8ec5505542c.

To get the ball rolling, I'm helping push forward the spec in the SDK. This was initially in Notion (https://www.notion.so/sentry/Logs-in-the-SDK-1a48b10e4b5d80b1827fe14d9fd0236b#1a58b10e4b5d80019d2eef6d84213d4a), but now we're moving it to develop so that we can work more in the open.

This PR documents:

  1. The idealized public api for logs
  2. The idealized sdk options for logs
  3. The otel log envelope format
  4. The recommended internal sdk behavior for logs

You'll notice only the otel_log envelope item is documented. This is what we used for the first alpha release of the SDK, but we'll be moving the SDKs to use the log envelope item instead. Until the logenvelope item protocol is finalized we are avoiding documenting in develop, but we marked it as TODO in the necessary sections. No longer applies log envelope item has been documented.

Rendered Preview:

@AbhiPrasadAbhiPrasad self-assigned this Mar 4, 2025
@vercel

vercelBot commented Mar 4, 2025

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for Git ↗︎

NameStatusPreviewCommentsUpdated (UTC)
develop-docs✅ Ready (Inspect)Visit Preview💬 Add feedbackApr 22, 2025 2:51pm
2 Skipped Deployments
NameStatusPreviewCommentsUpdated (UTC)
changelog⬜️ Ignored (Inspect)Visit PreviewApr 22, 2025 2:51pm
sentry-docs⬜️ Ignored (Inspect)Visit PreviewApr 22, 2025 2:51pm

@AbhiPrasadAbhiPrasad changed the title [WIP] feat(logs): intial work on develop docs for sdk logging apifeat(logs): intial work on develop docs for sdk logging apiMar 5, 2025
Comment threaddevelop-docs/sdk/data-model/envelope-items.mdx Outdated
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Co-authored-by: Alex Krawiec <alex.krawiec@sentry.io>
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Co-authored-by: Lorenzo Cian <lorenzo.cian@sentry.io>
Comment threaddevelop-docs/sdk/telemetry/logs.mdx
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Comment on lines +81 to +86
{
"key": "string_item",
"value": {
"stringValue": "value"
}
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I find this format quite clunky, is this how OTel does things? If we have some leeway here I think the following would already go a long way towards making this easier to work with:

  1. removing the extra nesting; i.e., not having "value" be a dictionary but rather the flat value
  2. instead of having different names for the key depending on the type, moving the type into its own key

So basically the above would become this:

Suggested change
{
"key": "string_item",
"value": {
"stringValue": "value"
}
},
{
"key": "string_item",
"value": "value",
"type": "string",
},

I'd especially like to do 2. since in Python it otherwise leads to some non-idiomatic code where instead of just accessing the value by key, you have to pop() from the dict instead. It's not a huge deal but I had to work with dicts like this and it felt very clunky.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nevermind, this is the format for otel_log so I guess we can't be creative here. :) But maybe we can come up with a nicer format for logs once we get to defining that.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I was also thinking that the format is a bit verbose. But as this is just the otel logs data model https://opentelemetry.io/docs/specs/otel/logs/data-model/ it is fine.

For the logs type I think we should also be as close to potel as possible. As this is an internal format and the user will probably never see this, it does not matter if it is a bit verbose.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we may be heading towards using AnyValue proto (the value type you're seeing here, from OTel) in our RPCs, in which case I think we may not want to be creative at all for the transport protocol for sdks since AnyValue will be used essentially everywhere in our product from ingest to rpc to frontend.

It may make more sense for the sdks to offer idiomatic apis that convert into our protocol, especially since the idioms differ anyway (eg. stringValue is fine in js since it's usually camelCase).

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

We've improved this with logs pageload, see 3ff6e56

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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should this be sentry.server.address?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

We're using the OTEL conventions directly here, so I feel fine with setting it this way. There's nothing specific about this attribute to sentry.

k-fish added a commit to getsentry/relay that referenced this pull request Apr 11, 2025
### Summary
Now that we've mostly finalized the logs protocol with sdks (see
[develop doc for more
info](getsentry/sentry-docs#12920)), we want to
update Relay to allow the 'log' item type to be sent in this format.
SDK's will likely primarily use the `log` ItemType instead of `otel_log`
since we don't need to change timestamp conventions, can send a
simplified `level` (see `OurLogLevel` added in this PR).
#### Schema changes
We've deprecated some fields in the protocol that only exist for OTEL:
- `severity_number` and `severity_text`, we're coercing these to
`level`, but we're keeping the original severity text and number as
attributes as OTel allows custom severity text.
- `observed_timestamp_nanos` is always set by relay regardless of what
is sent because Relay is the 'collector'. We have to leave this as an
attribute as well since it's being used by the existing consumer for
origin timestamp.
- `timestamp_nanos` becomes `timestamp: Timestamp`
- `trace_flags`, this is unused, and the consumer doesn't even store it
in the table. Will decide what to do with this later.
#### Future work
- The `ourlog_merge_otel` function can be trimmed down since we won't
need to fill in deprecated fields to send the same data to the kafka
consumer.
- We may need to transform the `OurLog` protocol from json received from
sdks to a generic EAP "trace items" kafka message that is essentially a
couple fields (eg. traceid) + a KVMap for `attributes`.
---------
Co-authored-by: Michi Hoffmann <cleptric@users.noreply.github.com>
Co-authored-by: David Herberth <david.herberth@sentry.io>

@cleptriccleptric left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Weeee :shipit:

*None*
`item_count`

: **integer, required.** The number of log items in the envelope.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
: **integer, required.** The number of log items in the envelope.
: **integer, required.** The number of log entries in the item.

It's just scoped to the item, unfortunately naming clashes here "log item" and "envelope item"

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Naming is hard - good catch, will fix.

@AbhiPrasad

Copy link
Copy Markdown
ContributorAuthor

This is ready to merge, will do so as soon as CI passes.

The only thing major TODO to iterate on this the default attributes section. Because this still has some open Q, I'm going to tackle this in a follow up.

@codecov

codecovBot commented Apr 22, 2025

Copy link
Copy Markdown

Bundle Report

Changes will increase total bundle size by 135 bytes (0.0%) ⬆️. This is within the configured threshold ✅

Detailed changes
Bundle nameSizeChange
sentry-docs-server-cjs11.14MB141 bytes (0.0%) ⬆️
sentry-docs-client-array-push9.47MB-6 bytes (-0.0%) ⬇️

Affected Assets, Files, and Routes:

view changes for bundle: sentry-docs-server-cjs

Assets Changed:

Asset NameSize ChangeTotal SizeChange (%)
1729.js-3 bytes1.75MB-0.0%
../instrumentation.js-3 bytes1.08MB-0.0%
9523.js-3 bytes1.05MB-0.0%
../app/[[...path]]/page.js.nft.json50 bytes388.48kB0.01%
../app/platform-redirect/page.js.nft.json50 bytes388.39kB0.01%
../app/sitemap.xml/route.js.nft.json50 bytes386.36kB0.01%
view changes for bundle: sentry-docs-client-array-push

Assets Changed:

Asset NameSize ChangeTotal SizeChange (%)
static/chunks/pages/_app-*.js-3 bytes868.7kB-0.0%
static/chunks/8165-*.js-3 bytes410.1kB-0.0%
server/middleware-*.js5.55kB6.55kB555.3% ⚠️
server/middleware-*.js-5.55kB1.0kB-84.74%
static/ys4-*.js(New)578 bytes578 bytes100.0% 🚀
static/ys4-*.js(New)77 bytes77 bytes100.0% 🚀
static/Yd0cqjRC-*.js(Deleted)-578 bytes0 bytes-100.0% 🗑️
static/Yd0cqjRC-*.js(Deleted)-77 bytes0 bytes-100.0% 🗑️

@AbhiPrasad
AbhiPrasad merged commit 385e6e6 into masterApr 22, 2025
@AbhiPrasad
AbhiPrasad deleted the abhi-logs-sdk-developer-documentation branch April 22, 2025 14:51
@github-actionsgithub-actionsBot locked and limited conversation to collaborators May 8, 2025
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Logs Section to Develop Docs

10 participants

@AbhiPrasad@antonpirker@Dav1dde@philipphofmann@romtsn@k-fish@cleptric@lcian@coolguyzone@sentrivana
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat(logs): initial work on develop docs for sdk logging api - #12920

Merged
AbhiPrasad merged 32 commits into
masterfrom
abhi-logs-sdk-developer-documentation
Apr 22, 2025
Merged

feat(logs): initial work on develop docs for sdk logging api#12920
AbhiPrasad merged 32 commits into
masterfrom
abhi-logs-sdk-developer-documentation

Conversation

@AbhiPrasad

@AbhiPrasadAbhiPrasad commented Mar 4, 2025

Copy link
Copy Markdown
Contributor

resolves#12870

Sentry is exploring an application logging product! More details here in our internal notion: https://www.notion.so/sentry/PRFAQ-Application-Logging-1258b10e4b5d80ea8e98e8ec5505542c.

To get the ball rolling, I'm helping push forward the spec in the SDK. This was initially in Notion (https://www.notion.so/sentry/Logs-in-the-SDK-1a48b10e4b5d80b1827fe14d9fd0236b#1a58b10e4b5d80019d2eef6d84213d4a), but now we're moving it to develop so that we can work more in the open.

This PR documents:

  1. The idealized public api for logs
  2. The idealized sdk options for logs
  3. The otel log envelope format
  4. The recommended internal sdk behavior for logs

You'll notice only the otel_log envelope item is documented. This is what we used for the first alpha release of the SDK, but we'll be moving the SDKs to use the log envelope item instead. Until the logenvelope item protocol is finalized we are avoiding documenting in develop, but we marked it as TODO in the necessary sections. No longer applies log envelope item has been documented.

Rendered Preview:

@AbhiPrasadAbhiPrasad self-assigned this Mar 4, 2025
@vercel

vercelBot commented Mar 4, 2025

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for Git ↗︎

NameStatusPreviewCommentsUpdated (UTC)
develop-docs✅ Ready (Inspect)Visit Preview💬 Add feedbackApr 22, 2025 2:51pm
2 Skipped Deployments
NameStatusPreviewCommentsUpdated (UTC)
changelog⬜️ Ignored (Inspect)Visit PreviewApr 22, 2025 2:51pm
sentry-docs⬜️ Ignored (Inspect)Visit PreviewApr 22, 2025 2:51pm

@AbhiPrasadAbhiPrasad changed the title [WIP] feat(logs): intial work on develop docs for sdk logging apifeat(logs): intial work on develop docs for sdk logging apiMar 5, 2025
Comment threaddevelop-docs/sdk/data-model/envelope-items.mdx Outdated
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Co-authored-by: Alex Krawiec <alex.krawiec@sentry.io>
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Co-authored-by: Lorenzo Cian <lorenzo.cian@sentry.io>
Comment threaddevelop-docs/sdk/telemetry/logs.mdx
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Comment on lines +81 to +86
{
"key": "string_item",
"value": {
"stringValue": "value"
}
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I find this format quite clunky, is this how OTel does things? If we have some leeway here I think the following would already go a long way towards making this easier to work with:

  1. removing the extra nesting; i.e., not having "value" be a dictionary but rather the flat value
  2. instead of having different names for the key depending on the type, moving the type into its own key

So basically the above would become this:

Suggested change
{
"key": "string_item",
"value": {
"stringValue": "value"
}
},
{
"key": "string_item",
"value": "value",
"type": "string",
},

I'd especially like to do 2. since in Python it otherwise leads to some non-idiomatic code where instead of just accessing the value by key, you have to pop() from the dict instead. It's not a huge deal but I had to work with dicts like this and it felt very clunky.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nevermind, this is the format for otel_log so I guess we can't be creative here. :) But maybe we can come up with a nicer format for logs once we get to defining that.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I was also thinking that the format is a bit verbose. But as this is just the otel logs data model https://opentelemetry.io/docs/specs/otel/logs/data-model/ it is fine.

For the logs type I think we should also be as close to potel as possible. As this is an internal format and the user will probably never see this, it does not matter if it is a bit verbose.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we may be heading towards using AnyValue proto (the value type you're seeing here, from OTel) in our RPCs, in which case I think we may not want to be creative at all for the transport protocol for sdks since AnyValue will be used essentially everywhere in our product from ingest to rpc to frontend.

It may make more sense for the sdks to offer idiomatic apis that convert into our protocol, especially since the idioms differ anyway (eg. stringValue is fine in js since it's usually camelCase).

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

We've improved this with logs pageload, see 3ff6e56

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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should this be sentry.server.address?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

We're using the OTEL conventions directly here, so I feel fine with setting it this way. There's nothing specific about this attribute to sentry.

k-fish added a commit to getsentry/relay that referenced this pull request Apr 11, 2025
### Summary
Now that we've mostly finalized the logs protocol with sdks (see
[develop doc for more
info](getsentry/sentry-docs#12920)), we want to
update Relay to allow the 'log' item type to be sent in this format.
SDK's will likely primarily use the `log` ItemType instead of `otel_log`
since we don't need to change timestamp conventions, can send a
simplified `level` (see `OurLogLevel` added in this PR).
#### Schema changes
We've deprecated some fields in the protocol that only exist for OTEL:
- `severity_number` and `severity_text`, we're coercing these to
`level`, but we're keeping the original severity text and number as
attributes as OTel allows custom severity text.
- `observed_timestamp_nanos` is always set by relay regardless of what
is sent because Relay is the 'collector'. We have to leave this as an
attribute as well since it's being used by the existing consumer for
origin timestamp.
- `timestamp_nanos` becomes `timestamp: Timestamp`
- `trace_flags`, this is unused, and the consumer doesn't even store it
in the table. Will decide what to do with this later.
#### Future work
- The `ourlog_merge_otel` function can be trimmed down since we won't
need to fill in deprecated fields to send the same data to the kafka
consumer.
- We may need to transform the `OurLog` protocol from json received from
sdks to a generic EAP "trace items" kafka message that is essentially a
couple fields (eg. traceid) + a KVMap for `attributes`.
---------
Co-authored-by: Michi Hoffmann <cleptric@users.noreply.github.com>
Co-authored-by: David Herberth <david.herberth@sentry.io>

@cleptriccleptric left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Weeee :shipit:

*None*
`item_count`

: **integer, required.** The number of log items in the envelope.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
: **integer, required.** The number of log items in the envelope.
: **integer, required.** The number of log entries in the item.

It's just scoped to the item, unfortunately naming clashes here "log item" and "envelope item"

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Naming is hard - good catch, will fix.

@AbhiPrasad

Copy link
Copy Markdown
ContributorAuthor

This is ready to merge, will do so as soon as CI passes.

The only thing major TODO to iterate on this the default attributes section. Because this still has some open Q, I'm going to tackle this in a follow up.

@codecov

codecovBot commented Apr 22, 2025

Copy link
Copy Markdown

Bundle Report

Changes will increase total bundle size by 135 bytes (0.0%) ⬆️. This is within the configured threshold ✅

Detailed changes
Bundle nameSizeChange
sentry-docs-server-cjs11.14MB141 bytes (0.0%) ⬆️
sentry-docs-client-array-push9.47MB-6 bytes (-0.0%) ⬇️

Affected Assets, Files, and Routes:

view changes for bundle: sentry-docs-server-cjs

Assets Changed:

Asset NameSize ChangeTotal SizeChange (%)
1729.js-3 bytes1.75MB-0.0%
../instrumentation.js-3 bytes1.08MB-0.0%
9523.js-3 bytes1.05MB-0.0%
../app/[[...path]]/page.js.nft.json50 bytes388.48kB0.01%
../app/platform-redirect/page.js.nft.json50 bytes388.39kB0.01%
../app/sitemap.xml/route.js.nft.json50 bytes386.36kB0.01%
view changes for bundle: sentry-docs-client-array-push

Assets Changed:

Asset NameSize ChangeTotal SizeChange (%)
static/chunks/pages/_app-*.js-3 bytes868.7kB-0.0%
static/chunks/8165-*.js-3 bytes410.1kB-0.0%
server/middleware-*.js5.55kB6.55kB555.3% ⚠️
server/middleware-*.js-5.55kB1.0kB-84.74%
static/ys4-*.js(New)578 bytes578 bytes100.0% 🚀
static/ys4-*.js(New)77 bytes77 bytes100.0% 🚀
static/Yd0cqjRC-*.js(Deleted)-578 bytes0 bytes-100.0% 🗑️
static/Yd0cqjRC-*.js(Deleted)-77 bytes0 bytes-100.0% 🗑️

@AbhiPrasad
AbhiPrasad merged commit 385e6e6 into masterApr 22, 2025
@AbhiPrasad
AbhiPrasad deleted the abhi-logs-sdk-developer-documentation branch April 22, 2025 14:51
@github-actionsgithub-actionsBot locked and limited conversation to collaborators May 8, 2025
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Logs Section to Develop Docs

10 participants

@AbhiPrasad@antonpirker@Dav1dde@philipphofmann@romtsn@k-fish@cleptric@lcian@coolguyzone@sentrivana
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(logs): initial work on develop docs for sdk logging api - #12920

Merged
AbhiPrasad merged 32 commits into
masterfrom
abhi-logs-sdk-developer-documentation
Apr 22, 2025
Merged

feat(logs): initial work on develop docs for sdk logging api#12920
AbhiPrasad merged 32 commits into
masterfrom
abhi-logs-sdk-developer-documentation

Conversation

@AbhiPrasad

@AbhiPrasadAbhiPrasad commented Mar 4, 2025

Copy link
Copy Markdown
Contributor

resolves#12870

Sentry is exploring an application logging product! More details here in our internal notion: https://www.notion.so/sentry/PRFAQ-Application-Logging-1258b10e4b5d80ea8e98e8ec5505542c.

To get the ball rolling, I'm helping push forward the spec in the SDK. This was initially in Notion (https://www.notion.so/sentry/Logs-in-the-SDK-1a48b10e4b5d80b1827fe14d9fd0236b#1a58b10e4b5d80019d2eef6d84213d4a), but now we're moving it to develop so that we can work more in the open.

This PR documents:

  1. The idealized public api for logs
  2. The idealized sdk options for logs
  3. The otel log envelope format
  4. The recommended internal sdk behavior for logs

You'll notice only the otel_log envelope item is documented. This is what we used for the first alpha release of the SDK, but we'll be moving the SDKs to use the log envelope item instead. Until the logenvelope item protocol is finalized we are avoiding documenting in develop, but we marked it as TODO in the necessary sections. No longer applies log envelope item has been documented.

Rendered Preview:

@AbhiPrasadAbhiPrasad self-assigned this Mar 4, 2025
@vercel

vercelBot commented Mar 4, 2025

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for Git ↗︎

NameStatusPreviewCommentsUpdated (UTC)
develop-docs✅ Ready (Inspect)Visit Preview💬 Add feedbackApr 22, 2025 2:51pm
2 Skipped Deployments
NameStatusPreviewCommentsUpdated (UTC)
changelog⬜️ Ignored (Inspect)Visit PreviewApr 22, 2025 2:51pm
sentry-docs⬜️ Ignored (Inspect)Visit PreviewApr 22, 2025 2:51pm

@AbhiPrasadAbhiPrasad changed the title [WIP] feat(logs): intial work on develop docs for sdk logging apifeat(logs): intial work on develop docs for sdk logging apiMar 5, 2025
Comment threaddevelop-docs/sdk/data-model/envelope-items.mdx Outdated
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Co-authored-by: Alex Krawiec <alex.krawiec@sentry.io>
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Co-authored-by: Lorenzo Cian <lorenzo.cian@sentry.io>
Comment threaddevelop-docs/sdk/telemetry/logs.mdx
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Comment on lines +81 to +86
{
"key": "string_item",
"value": {
"stringValue": "value"
}
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I find this format quite clunky, is this how OTel does things? If we have some leeway here I think the following would already go a long way towards making this easier to work with:

  1. removing the extra nesting; i.e., not having "value" be a dictionary but rather the flat value
  2. instead of having different names for the key depending on the type, moving the type into its own key

So basically the above would become this:

Suggested change
{
"key": "string_item",
"value": {
"stringValue": "value"
}
},
{
"key": "string_item",
"value": "value",
"type": "string",
},

I'd especially like to do 2. since in Python it otherwise leads to some non-idiomatic code where instead of just accessing the value by key, you have to pop() from the dict instead. It's not a huge deal but I had to work with dicts like this and it felt very clunky.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nevermind, this is the format for otel_log so I guess we can't be creative here. :) But maybe we can come up with a nicer format for logs once we get to defining that.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I was also thinking that the format is a bit verbose. But as this is just the otel logs data model https://opentelemetry.io/docs/specs/otel/logs/data-model/ it is fine.

For the logs type I think we should also be as close to potel as possible. As this is an internal format and the user will probably never see this, it does not matter if it is a bit verbose.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we may be heading towards using AnyValue proto (the value type you're seeing here, from OTel) in our RPCs, in which case I think we may not want to be creative at all for the transport protocol for sdks since AnyValue will be used essentially everywhere in our product from ingest to rpc to frontend.

It may make more sense for the sdks to offer idiomatic apis that convert into our protocol, especially since the idioms differ anyway (eg. stringValue is fine in js since it's usually camelCase).

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

We've improved this with logs pageload, see 3ff6e56

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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should this be sentry.server.address?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

We're using the OTEL conventions directly here, so I feel fine with setting it this way. There's nothing specific about this attribute to sentry.

k-fish added a commit to getsentry/relay that referenced this pull request Apr 11, 2025
### Summary
Now that we've mostly finalized the logs protocol with sdks (see
[develop doc for more
info](getsentry/sentry-docs#12920)), we want to
update Relay to allow the 'log' item type to be sent in this format.
SDK's will likely primarily use the `log` ItemType instead of `otel_log`
since we don't need to change timestamp conventions, can send a
simplified `level` (see `OurLogLevel` added in this PR).
#### Schema changes
We've deprecated some fields in the protocol that only exist for OTEL:
- `severity_number` and `severity_text`, we're coercing these to
`level`, but we're keeping the original severity text and number as
attributes as OTel allows custom severity text.
- `observed_timestamp_nanos` is always set by relay regardless of what
is sent because Relay is the 'collector'. We have to leave this as an
attribute as well since it's being used by the existing consumer for
origin timestamp.
- `timestamp_nanos` becomes `timestamp: Timestamp`
- `trace_flags`, this is unused, and the consumer doesn't even store it
in the table. Will decide what to do with this later.
#### Future work
- The `ourlog_merge_otel` function can be trimmed down since we won't
need to fill in deprecated fields to send the same data to the kafka
consumer.
- We may need to transform the `OurLog` protocol from json received from
sdks to a generic EAP "trace items" kafka message that is essentially a
couple fields (eg. traceid) + a KVMap for `attributes`.
---------
Co-authored-by: Michi Hoffmann <cleptric@users.noreply.github.com>
Co-authored-by: David Herberth <david.herberth@sentry.io>

@cleptriccleptric left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Weeee :shipit:

*None*
`item_count`

: **integer, required.** The number of log items in the envelope.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
: **integer, required.** The number of log items in the envelope.
: **integer, required.** The number of log entries in the item.

It's just scoped to the item, unfortunately naming clashes here "log item" and "envelope item"

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Naming is hard - good catch, will fix.

@AbhiPrasad

Copy link
Copy Markdown
ContributorAuthor

This is ready to merge, will do so as soon as CI passes.

The only thing major TODO to iterate on this the default attributes section. Because this still has some open Q, I'm going to tackle this in a follow up.

@codecov

codecovBot commented Apr 22, 2025

Copy link
Copy Markdown

Bundle Report

Changes will increase total bundle size by 135 bytes (0.0%) ⬆️. This is within the configured threshold ✅

Detailed changes
Bundle nameSizeChange
sentry-docs-server-cjs11.14MB141 bytes (0.0%) ⬆️
sentry-docs-client-array-push9.47MB-6 bytes (-0.0%) ⬇️

Affected Assets, Files, and Routes:

view changes for bundle: sentry-docs-server-cjs

Assets Changed:

Asset NameSize ChangeTotal SizeChange (%)
1729.js-3 bytes1.75MB-0.0%
../instrumentation.js-3 bytes1.08MB-0.0%
9523.js-3 bytes1.05MB-0.0%
../app/[[...path]]/page.js.nft.json50 bytes388.48kB0.01%
../app/platform-redirect/page.js.nft.json50 bytes388.39kB0.01%
../app/sitemap.xml/route.js.nft.json50 bytes386.36kB0.01%
view changes for bundle: sentry-docs-client-array-push

Assets Changed:

Asset NameSize ChangeTotal SizeChange (%)
static/chunks/pages/_app-*.js-3 bytes868.7kB-0.0%
static/chunks/8165-*.js-3 bytes410.1kB-0.0%
server/middleware-*.js5.55kB6.55kB555.3% ⚠️
server/middleware-*.js-5.55kB1.0kB-84.74%
static/ys4-*.js(New)578 bytes578 bytes100.0% 🚀
static/ys4-*.js(New)77 bytes77 bytes100.0% 🚀
static/Yd0cqjRC-*.js(Deleted)-578 bytes0 bytes-100.0% 🗑️
static/Yd0cqjRC-*.js(Deleted)-77 bytes0 bytes-100.0% 🗑️

@AbhiPrasad
AbhiPrasad merged commit 385e6e6 into masterApr 22, 2025
@AbhiPrasad
AbhiPrasad deleted the abhi-logs-sdk-developer-documentation branch April 22, 2025 14:51
@github-actionsgithub-actionsBot locked and limited conversation to collaborators May 8, 2025
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Logs Section to Develop Docs

10 participants

@AbhiPrasad@antonpirker@Dav1dde@philipphofmann@romtsn@k-fish@cleptric@lcian@coolguyzone@sentrivana
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(logs): initial work on develop docs for sdk logging api - #12920

Merged
AbhiPrasad merged 32 commits into
masterfrom
abhi-logs-sdk-developer-documentation
Apr 22, 2025
Merged

feat(logs): initial work on develop docs for sdk logging api#12920
AbhiPrasad merged 32 commits into
masterfrom
abhi-logs-sdk-developer-documentation

Conversation

@AbhiPrasad

@AbhiPrasadAbhiPrasad commented Mar 4, 2025

Copy link
Copy Markdown
Contributor

resolves#12870

Sentry is exploring an application logging product! More details here in our internal notion: https://www.notion.so/sentry/PRFAQ-Application-Logging-1258b10e4b5d80ea8e98e8ec5505542c.

To get the ball rolling, I'm helping push forward the spec in the SDK. This was initially in Notion (https://www.notion.so/sentry/Logs-in-the-SDK-1a48b10e4b5d80b1827fe14d9fd0236b#1a58b10e4b5d80019d2eef6d84213d4a), but now we're moving it to develop so that we can work more in the open.

This PR documents:

  1. The idealized public api for logs
  2. The idealized sdk options for logs
  3. The otel log envelope format
  4. The recommended internal sdk behavior for logs

You'll notice only the otel_log envelope item is documented. This is what we used for the first alpha release of the SDK, but we'll be moving the SDKs to use the log envelope item instead. Until the logenvelope item protocol is finalized we are avoiding documenting in develop, but we marked it as TODO in the necessary sections. No longer applies log envelope item has been documented.

Rendered Preview:

@AbhiPrasadAbhiPrasad self-assigned this Mar 4, 2025
@vercel

vercelBot commented Mar 4, 2025

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for Git ↗︎

NameStatusPreviewCommentsUpdated (UTC)
develop-docs✅ Ready (Inspect)Visit Preview💬 Add feedbackApr 22, 2025 2:51pm
2 Skipped Deployments
NameStatusPreviewCommentsUpdated (UTC)
changelog⬜️ Ignored (Inspect)Visit PreviewApr 22, 2025 2:51pm
sentry-docs⬜️ Ignored (Inspect)Visit PreviewApr 22, 2025 2:51pm

@AbhiPrasadAbhiPrasad changed the title [WIP] feat(logs): intial work on develop docs for sdk logging apifeat(logs): intial work on develop docs for sdk logging apiMar 5, 2025
Comment threaddevelop-docs/sdk/data-model/envelope-items.mdx Outdated
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Co-authored-by: Alex Krawiec <alex.krawiec@sentry.io>
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Co-authored-by: Lorenzo Cian <lorenzo.cian@sentry.io>
Comment threaddevelop-docs/sdk/telemetry/logs.mdx
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Comment on lines +81 to +86
{
"key": "string_item",
"value": {
"stringValue": "value"
}
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I find this format quite clunky, is this how OTel does things? If we have some leeway here I think the following would already go a long way towards making this easier to work with:

  1. removing the extra nesting; i.e., not having "value" be a dictionary but rather the flat value
  2. instead of having different names for the key depending on the type, moving the type into its own key

So basically the above would become this:

Suggested change
{
"key": "string_item",
"value": {
"stringValue": "value"
}
},
{
"key": "string_item",
"value": "value",
"type": "string",
},

I'd especially like to do 2. since in Python it otherwise leads to some non-idiomatic code where instead of just accessing the value by key, you have to pop() from the dict instead. It's not a huge deal but I had to work with dicts like this and it felt very clunky.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nevermind, this is the format for otel_log so I guess we can't be creative here. :) But maybe we can come up with a nicer format for logs once we get to defining that.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I was also thinking that the format is a bit verbose. But as this is just the otel logs data model https://opentelemetry.io/docs/specs/otel/logs/data-model/ it is fine.

For the logs type I think we should also be as close to potel as possible. As this is an internal format and the user will probably never see this, it does not matter if it is a bit verbose.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we may be heading towards using AnyValue proto (the value type you're seeing here, from OTel) in our RPCs, in which case I think we may not want to be creative at all for the transport protocol for sdks since AnyValue will be used essentially everywhere in our product from ingest to rpc to frontend.

It may make more sense for the sdks to offer idiomatic apis that convert into our protocol, especially since the idioms differ anyway (eg. stringValue is fine in js since it's usually camelCase).

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

We've improved this with logs pageload, see 3ff6e56

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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should this be sentry.server.address?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

We're using the OTEL conventions directly here, so I feel fine with setting it this way. There's nothing specific about this attribute to sentry.

k-fish added a commit to getsentry/relay that referenced this pull request Apr 11, 2025
### Summary
Now that we've mostly finalized the logs protocol with sdks (see
[develop doc for more
info](getsentry/sentry-docs#12920)), we want to
update Relay to allow the 'log' item type to be sent in this format.
SDK's will likely primarily use the `log` ItemType instead of `otel_log`
since we don't need to change timestamp conventions, can send a
simplified `level` (see `OurLogLevel` added in this PR).
#### Schema changes
We've deprecated some fields in the protocol that only exist for OTEL:
- `severity_number` and `severity_text`, we're coercing these to
`level`, but we're keeping the original severity text and number as
attributes as OTel allows custom severity text.
- `observed_timestamp_nanos` is always set by relay regardless of what
is sent because Relay is the 'collector'. We have to leave this as an
attribute as well since it's being used by the existing consumer for
origin timestamp.
- `timestamp_nanos` becomes `timestamp: Timestamp`
- `trace_flags`, this is unused, and the consumer doesn't even store it
in the table. Will decide what to do with this later.
#### Future work
- The `ourlog_merge_otel` function can be trimmed down since we won't
need to fill in deprecated fields to send the same data to the kafka
consumer.
- We may need to transform the `OurLog` protocol from json received from
sdks to a generic EAP "trace items" kafka message that is essentially a
couple fields (eg. traceid) + a KVMap for `attributes`.
---------
Co-authored-by: Michi Hoffmann <cleptric@users.noreply.github.com>
Co-authored-by: David Herberth <david.herberth@sentry.io>

@cleptriccleptric left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Weeee :shipit:

*None*
`item_count`

: **integer, required.** The number of log items in the envelope.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
: **integer, required.** The number of log items in the envelope.
: **integer, required.** The number of log entries in the item.

It's just scoped to the item, unfortunately naming clashes here "log item" and "envelope item"

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Naming is hard - good catch, will fix.

@AbhiPrasad

Copy link
Copy Markdown
ContributorAuthor

This is ready to merge, will do so as soon as CI passes.

The only thing major TODO to iterate on this the default attributes section. Because this still has some open Q, I'm going to tackle this in a follow up.

@codecov

codecovBot commented Apr 22, 2025

Copy link
Copy Markdown

Bundle Report

Changes will increase total bundle size by 135 bytes (0.0%) ⬆️. This is within the configured threshold ✅

Detailed changes
Bundle nameSizeChange
sentry-docs-server-cjs11.14MB141 bytes (0.0%) ⬆️
sentry-docs-client-array-push9.47MB-6 bytes (-0.0%) ⬇️

Affected Assets, Files, and Routes:

view changes for bundle: sentry-docs-server-cjs

Assets Changed:

Asset NameSize ChangeTotal SizeChange (%)
1729.js-3 bytes1.75MB-0.0%
../instrumentation.js-3 bytes1.08MB-0.0%
9523.js-3 bytes1.05MB-0.0%
../app/[[...path]]/page.js.nft.json50 bytes388.48kB0.01%
../app/platform-redirect/page.js.nft.json50 bytes388.39kB0.01%
../app/sitemap.xml/route.js.nft.json50 bytes386.36kB0.01%
view changes for bundle: sentry-docs-client-array-push

Assets Changed:

Asset NameSize ChangeTotal SizeChange (%)
static/chunks/pages/_app-*.js-3 bytes868.7kB-0.0%
static/chunks/8165-*.js-3 bytes410.1kB-0.0%
server/middleware-*.js5.55kB6.55kB555.3% ⚠️
server/middleware-*.js-5.55kB1.0kB-84.74%
static/ys4-*.js(New)578 bytes578 bytes100.0% 🚀
static/ys4-*.js(New)77 bytes77 bytes100.0% 🚀
static/Yd0cqjRC-*.js(Deleted)-578 bytes0 bytes-100.0% 🗑️
static/Yd0cqjRC-*.js(Deleted)-77 bytes0 bytes-100.0% 🗑️

@AbhiPrasad
AbhiPrasad merged commit 385e6e6 into masterApr 22, 2025
@AbhiPrasad
AbhiPrasad deleted the abhi-logs-sdk-developer-documentation branch April 22, 2025 14:51
@github-actionsgithub-actionsBot locked and limited conversation to collaborators May 8, 2025
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Logs Section to Develop Docs

10 participants

@AbhiPrasad@antonpirker@Dav1dde@philipphofmann@romtsn@k-fish@cleptric@lcian@coolguyzone@sentrivana
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat(logs): initial work on develop docs for sdk logging api - #12920

Merged
AbhiPrasad merged 32 commits into
masterfrom
abhi-logs-sdk-developer-documentation
Apr 22, 2025
Merged

feat(logs): initial work on develop docs for sdk logging api#12920
AbhiPrasad merged 32 commits into
masterfrom
abhi-logs-sdk-developer-documentation

Conversation

@AbhiPrasad

@AbhiPrasadAbhiPrasad commented Mar 4, 2025

Copy link
Copy Markdown
Contributor

resolves#12870

Sentry is exploring an application logging product! More details here in our internal notion: https://www.notion.so/sentry/PRFAQ-Application-Logging-1258b10e4b5d80ea8e98e8ec5505542c.

To get the ball rolling, I'm helping push forward the spec in the SDK. This was initially in Notion (https://www.notion.so/sentry/Logs-in-the-SDK-1a48b10e4b5d80b1827fe14d9fd0236b#1a58b10e4b5d80019d2eef6d84213d4a), but now we're moving it to develop so that we can work more in the open.

This PR documents:

  1. The idealized public api for logs
  2. The idealized sdk options for logs
  3. The otel log envelope format
  4. The recommended internal sdk behavior for logs

You'll notice only the otel_log envelope item is documented. This is what we used for the first alpha release of the SDK, but we'll be moving the SDKs to use the log envelope item instead. Until the logenvelope item protocol is finalized we are avoiding documenting in develop, but we marked it as TODO in the necessary sections. No longer applies log envelope item has been documented.

Rendered Preview:

@AbhiPrasadAbhiPrasad self-assigned this Mar 4, 2025
@vercel

vercelBot commented Mar 4, 2025

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for Git ↗︎

NameStatusPreviewCommentsUpdated (UTC)
develop-docs✅ Ready (Inspect)Visit Preview💬 Add feedbackApr 22, 2025 2:51pm
2 Skipped Deployments
NameStatusPreviewCommentsUpdated (UTC)
changelog⬜️ Ignored (Inspect)Visit PreviewApr 22, 2025 2:51pm
sentry-docs⬜️ Ignored (Inspect)Visit PreviewApr 22, 2025 2:51pm

@AbhiPrasadAbhiPrasad changed the title [WIP] feat(logs): intial work on develop docs for sdk logging apifeat(logs): intial work on develop docs for sdk logging apiMar 5, 2025
Comment threaddevelop-docs/sdk/data-model/envelope-items.mdx Outdated
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Co-authored-by: Alex Krawiec <alex.krawiec@sentry.io>
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Co-authored-by: Lorenzo Cian <lorenzo.cian@sentry.io>
Comment threaddevelop-docs/sdk/telemetry/logs.mdx
Comment threaddevelop-docs/sdk/telemetry/logs.mdx Outdated
Comment on lines +81 to +86
{
"key": "string_item",
"value": {
"stringValue": "value"
}
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I find this format quite clunky, is this how OTel does things? If we have some leeway here I think the following would already go a long way towards making this easier to work with:

  1. removing the extra nesting; i.e., not having "value" be a dictionary but rather the flat value
  2. instead of having different names for the key depending on the type, moving the type into its own key

So basically the above would become this:

Suggested change
{
"key": "string_item",
"value": {
"stringValue": "value"
}
},
{
"key": "string_item",
"value": "value",
"type": "string",
},

I'd especially like to do 2. since in Python it otherwise leads to some non-idiomatic code where instead of just accessing the value by key, you have to pop() from the dict instead. It's not a huge deal but I had to work with dicts like this and it felt very clunky.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nevermind, this is the format for otel_log so I guess we can't be creative here. :) But maybe we can come up with a nicer format for logs once we get to defining that.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I was also thinking that the format is a bit verbose. But as this is just the otel logs data model https://opentelemetry.io/docs/specs/otel/logs/data-model/ it is fine.

For the logs type I think we should also be as close to potel as possible. As this is an internal format and the user will probably never see this, it does not matter if it is a bit verbose.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we may be heading towards using AnyValue proto (the value type you're seeing here, from OTel) in our RPCs, in which case I think we may not want to be creative at all for the transport protocol for sdks since AnyValue will be used essentially everywhere in our product from ingest to rpc to frontend.

It may make more sense for the sdks to offer idiomatic apis that convert into our protocol, especially since the idioms differ anyway (eg. stringValue is fine in js since it's usually camelCase).

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

We've improved this with logs pageload, see 3ff6e56

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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should this be sentry.server.address?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

We're using the OTEL conventions directly here, so I feel fine with setting it this way. There's nothing specific about this attribute to sentry.

k-fish added a commit to getsentry/relay that referenced this pull request Apr 11, 2025
### Summary
Now that we've mostly finalized the logs protocol with sdks (see
[develop doc for more
info](getsentry/sentry-docs#12920)), we want to
update Relay to allow the 'log' item type to be sent in this format.
SDK's will likely primarily use the `log` ItemType instead of `otel_log`
since we don't need to change timestamp conventions, can send a
simplified `level` (see `OurLogLevel` added in this PR).
#### Schema changes
We've deprecated some fields in the protocol that only exist for OTEL:
- `severity_number` and `severity_text`, we're coercing these to
`level`, but we're keeping the original severity text and number as
attributes as OTel allows custom severity text.
- `observed_timestamp_nanos` is always set by relay regardless of what
is sent because Relay is the 'collector'. We have to leave this as an
attribute as well since it's being used by the existing consumer for
origin timestamp.
- `timestamp_nanos` becomes `timestamp: Timestamp`
- `trace_flags`, this is unused, and the consumer doesn't even store it
in the table. Will decide what to do with this later.
#### Future work
- The `ourlog_merge_otel` function can be trimmed down since we won't
need to fill in deprecated fields to send the same data to the kafka
consumer.
- We may need to transform the `OurLog` protocol from json received from
sdks to a generic EAP "trace items" kafka message that is essentially a
couple fields (eg. traceid) + a KVMap for `attributes`.
---------
Co-authored-by: Michi Hoffmann <cleptric@users.noreply.github.com>
Co-authored-by: David Herberth <david.herberth@sentry.io>

@cleptriccleptric left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Weeee :shipit:

*None*
`item_count`

: **integer, required.** The number of log items in the envelope.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
: **integer, required.** The number of log items in the envelope.
: **integer, required.** The number of log entries in the item.

It's just scoped to the item, unfortunately naming clashes here "log item" and "envelope item"

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Naming is hard - good catch, will fix.

@AbhiPrasad

Copy link
Copy Markdown
ContributorAuthor

This is ready to merge, will do so as soon as CI passes.

The only thing major TODO to iterate on this the default attributes section. Because this still has some open Q, I'm going to tackle this in a follow up.

@codecov

codecovBot commented Apr 22, 2025

Copy link
Copy Markdown

Bundle Report

Changes will increase total bundle size by 135 bytes (0.0%) ⬆️. This is within the configured threshold ✅

Detailed changes
Bundle nameSizeChange
sentry-docs-server-cjs11.14MB141 bytes (0.0%) ⬆️
sentry-docs-client-array-push9.47MB-6 bytes (-0.0%) ⬇️

Affected Assets, Files, and Routes:

view changes for bundle: sentry-docs-server-cjs

Assets Changed:

Asset NameSize ChangeTotal SizeChange (%)
1729.js-3 bytes1.75MB-0.0%
../instrumentation.js-3 bytes1.08MB-0.0%
9523.js-3 bytes1.05MB-0.0%
../app/[[...path]]/page.js.nft.json50 bytes388.48kB0.01%
../app/platform-redirect/page.js.nft.json50 bytes388.39kB0.01%
../app/sitemap.xml/route.js.nft.json50 bytes386.36kB0.01%
view changes for bundle: sentry-docs-client-array-push

Assets Changed:

Asset NameSize ChangeTotal SizeChange (%)
static/chunks/pages/_app-*.js-3 bytes868.7kB-0.0%
static/chunks/8165-*.js-3 bytes410.1kB-0.0%
server/middleware-*.js5.55kB6.55kB555.3% ⚠️
server/middleware-*.js-5.55kB1.0kB-84.74%
static/ys4-*.js(New)578 bytes578 bytes100.0% 🚀
static/ys4-*.js(New)77 bytes77 bytes100.0% 🚀
static/Yd0cqjRC-*.js(Deleted)-578 bytes0 bytes-100.0% 🗑️
static/Yd0cqjRC-*.js(Deleted)-77 bytes0 bytes-100.0% 🗑️

@AbhiPrasad
AbhiPrasad merged commit 385e6e6 into masterApr 22, 2025
@AbhiPrasad
AbhiPrasad deleted the abhi-logs-sdk-developer-documentation branch April 22, 2025 14:51
@github-actionsgithub-actionsBot locked and limited conversation to collaborators May 8, 2025
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Logs Section to Develop Docs

10 participants

@AbhiPrasad@antonpirker@Dav1dde@philipphofmann@romtsn@k-fish@cleptric@lcian@coolguyzone@sentrivana