feat(sdk-logs)!: implement scope attributes for logger creation#6573
feat(sdk-logs)!: implement scope attributes for logger creation#6573pichlermarc wants to merge 14 commits into
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #6573 +/- ##
=======================================
Coverage 94.85% 94.85%
=======================================
Files 377 377
Lines 12751 12816 +65
Branches 2887 2913 +26
=======================================
+ Hits 12095 12157 +62
- Misses 656 659 +3
🚀 New features to boost your workflow:
|
61b7daf to
c9cf015
Compare
|
|
||
| const ismKey = `${name}@${version}:${schemaUrl}`; | ||
| let records = ismMap.get(ismKey); | ||
| let records = ismMap.get(instrumentationScope); |
There was a problem hiding this comment.
note for reviewers: by avoding this string operation we get a significant performance boost for JSON serialization. we already do this in the protobuf serializer for performance reasons. Having to the string operation for each log record with scopeAttributes would be quite expensive.
Old:
transform 512 logs (json) x 734 ops/sec ±0.33% (97 runs sampled)
New:
transform 512 logs (json) x 770 ops/sec ±0.78% (92 runs sampled)
| diag.warn(`Invalid attribute key: ${key}`); | ||
| droppedAttributesCount++; | ||
| continue; | ||
| } | ||
|
|
||
| if (!isLogAttributeValue(value)) { | ||
| diag.warn(`Invalid attribute value set for key: ${key}`); | ||
| droppedAttributesCount++; |
There was a problem hiding this comment.
Whether to incr droppedAttributesCount for invalid keys.
The proto says:
https://github.com/open-telemetry/opentelemetry-proto/blob/aca87357903c668e441718a144be0adf435afec1/opentelemetry/proto/common/v1/common.proto#L116-L119
// The number of attributes that were discarded. Attributes
// can be discarded because their keys are too long or because there are too many
// attributes. If this value is 0, then no attributes were dropped.
uint32 dropped_attributes_count = 4;which suggests maybe not increment for invalid given keys.
The current LogRecord.setAttribute() does not incr for invalid keys:
opentelemetry-js/experimental/packages/sdk-logs/src/LogRecordImpl.ts
Lines 128 to 143 in 87d0112
Ultimately there should be one shared utility that handles applying (a) validation (that given attribute values are of supported types) and (b) limits.
I am fine refining this over a couple of PRs, however. I.e. doesn't have to be in this PR.
There was a problem hiding this comment.
Hmm interesting, the comment in the proto looked to me like it's giving examples of what could lead to dropped attributes, not an exhaustive list.
The spec mentions this about what makes an attributes valid/invalid:
An
Attributeis a key-value pair, which MUST have the following properties:
- The attribute key MUST be a non-
nulland non-empty string.
- Case sensitivity of keys is preserved. Keys that differ in casing are treated as distinct keys.
- The attribute value MUST be one of types defined in AnyValue.
The current LogRecord.setAttribute() does not incr for invalid keys
Hmm, I think we should increment since there is data that's potentially being dropped. I'll check what other SDKs are doing and will report back here.
Ultimately there should be one shared utility that handles applying (a) validation (that given attribute values are of supported types) and (b) limits.
Yep, I think that's a good idea. I'll look to consolidate some of the code in the logs SDK first. Looking at the spec again, we should apply limits in scope attributes too.
There was a problem hiding this comment.
I refactored some of the code to so that we have a shared utility in the Logs SDK for handling limits and adding attributes. Now it also applies limits for scope-attributes.
I've not changed behavior yet how we count dropped attributes, though. Please let me know if we should change one of them (either scope attr handling, or log record attr handling) 🙂
Ref: 98b6f26
| import { LogRecordImpl } from './LogRecordImpl'; | ||
| import type { LoggerProviderSharedState } from './internal/LoggerProviderSharedState'; | ||
| import type { LoggerConfig } from './types'; | ||
| import type { LogInstrumentationScope } from './internal/utils'; |
There was a problem hiding this comment.
Assuming #6349 or similar adds ExtendedAttributes to the @opentelemetry/api, would we want to consider updating InstrumentationScope in @opentelemetry/core to support attributes, rather than adding a separate LogInstrumentationScope type?
There was a problem hiding this comment.
would we want to consider updating InstrumentationScope in @opentelemetry/core to support attributes, rather than adding a separate LogInstrumentationScope type?
Yes, that's what I was thinking - also the reason why LogInstrumentationScope is not public yet; I'd rather have the type definition duplicated right now so that we don't need to deprecate and remove it later.
I'd like to implement this also for metrics and traces in a similar way. I want to:
- extend the
instrumentationScopeproperties in signal SDKs like so:InstrumentationScope & { attributes?: ExtendedAttributes, droppedAttributesCount?: number } - update
InstrumentationScopein@opentelemetry/coreso that it also contains these, and remove the extensions in the signal SDKs again so that it's unified across the board.
One caveat that just came to mind: we can only use the ExtendedAttributes in @opentelemetry/core@3.0.0. That's because we'd have to raise the minimum supported API version to use the new type exported from the future @opentelemetry/api@1.10.0
There was a problem hiding this comment.
If we agree that this is what we want to do I'll create some issues so that we don't forget when we work on 3.x :)
There was a problem hiding this comment.
If we agree that this is what we want to do
Yes.
One caveat that just came to mind: we can only use the
ExtendedAttributesin@opentelemetry/core@3.0.0. That's because we'd have to raise the minimum supported API version to use the new type exported from the future@opentelemetry/api@1.10.0
I agree.
(Aside: This paragraph is just sharing, and not suggesting anything concrete for this PR. What constitutes a breaking change here is still twisting my mind. My gut tells me that it is wrong that @opentelemetry/core should need a major version bump to add runtime support for a wider attributes type. I'm fairly confident I understand the "because we are sharing interface ExtendedAttributes" issue. However, I feel there should be a solution here. I don't know if it is a copied interface ExtendedAttributes that lives in @opentelemetry/core, or a separate @opentelemetry/api-types types-only package that both API and SDK packages use, or what. I haven't taken the time to play around here.)
There was a problem hiding this comment.
However, I feel there should be a solution here. I don't know if it is a copied interface ExtendedAttributes that lives in @opentelemetry/core, or a separate @opentelemetry/api-types types-only package that both API and SDK packages use, or what. I haven't taken the time to play around here.)
Mhm, the approach of copying the type is what we did in the past, since it was the simplest at the time (we only had to copy it to one place). I think we can do the same here.
163488b to
ec46c6b
Compare
Which problem is this PR solving?
The spec defines a concept called scope attributes - another level of attribute that's attached to the scope instead of the resource or log records.
To prepare for the upcoming Logs SDK/API GA, this PR:
scopeAttributessupport inLoggerProvider#getLogger()([sdk-logs] implement scopeAttributes #6413)scopeAttributessupport in the OTLP export pipeline ([sdk-logs] implement scopeAttributes #6413)Note on performance: With the changes proposed in this PR, use of
scopeAttributeswithLoggerProvider#getLogger()has a noticeable performance impact as attributes contribute to theLogger's identity. I decided to implement it this way, as it allows us to front-load the performance impact in a way that's easy the end-user to control as well as predictable regardless of which exporter is used.If we were not do it this way, there would be no efficient way to sort and batch by scope in the exporters, which would require us to perform the same operation numerous times to de-dupe scopes - this would have a guaranteed performance impact on each export cycle. Creating
Loggers should not be something that happens on a hot-path - the added API documentation also now warns the user thatLoggerProvider#getLogger()may be an expensive operation.Disclosure of AI use: I used Claude Haiku 4.5 for generating small bits and pieces of this PR, mostly tests and docs.
Fixes #6413
Type of change
How Has This Been Tested?