Skip to content

Conversation

Alec2435
Copy link

Make Log Attributes fully spec compliant and handle circular references

Which problem is this PR solving?

The current Log Attributes implementation is not fully compliant with the OpenTelemetry specification. The specification states that Log Attributes should support "any type, a superset of standard Attribute" including:

  • Byte arrays (Uint8Array)
  • Heterogeneous arrays (mixed types like [1, "two", true, null])
  • Nested objects/maps with recursive AnyValue support
  • Empty objects ({})
  • Null/undefined values

However, the current implementation uses the restrictive isAttributeValue() function from @opentelemetry/core which only supports homogeneous arrays and primitives. Additionally, there was an early return for null values preventing spec-compliant null attributes from being set.

This PR also addresses the circular reference investigation requested in the logs roadmap by implementing proper circular reference detection and handling.

Fixes #5744

Short description of the changes

  1. Created isLogAttributeValue() validation function in @opentelemetry/api-logs that supports all AnyValue types per the OpenTelemetry spec
  2. Added circular reference detection using WeakSet to prevent stack overflow during validation
  3. Updated LogRecordImpl to use the new spec-compliant validation function
  4. Enhanced truncation logic to handle nested objects and heterogeneous arrays
  5. Removed null value early return to allow spec-compliant null attributes
  6. Added comprehensive test coverage with 32+ tests covering all spec requirements and edge cases

Type of change

Please delete options that are not relevant.

  • New feature (non-breaking change which adds functionality)
  • Bug fix (non-breaking change which fixes an issue)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

  • Full test suite passes: All existing tests continue to pass (101 passing, 0 failing)
  • New validation function tests: 32 comprehensive tests in validation.test.ts covering:
    • All scalar values (string, number, boolean)
    • Byte arrays (Uint8Array)
    • Heterogeneous arrays with mixed types
    • Nested objects and complex combinations
    • Circular reference detection and graceful handling
    • Invalid value rejection (functions, symbols, built-in objects)
    • Edge cases (deep nesting, large arrays)
  • LogRecord integration tests: 15 new tests in LogRecord.test.ts verifying:
    • All AnyValue types work with setAttribute()
    • Proper truncation of strings in complex structures
    • Null/undefined value support
    • Complex nested attribute structures

Checklist:

  • Followed the style guidelines of this project
  • Unit tests have been added
  • Documentation has been updated (via comprehensive test documentation and JSDoc comments)

Files changed:

  • experimental/packages/api-logs/src/utils/validation.ts (new)
  • experimental/packages/api-logs/src/index.ts (export added)
  • experimental/packages/api-logs/test/common/utils/validation.test.ts (new)
  • experimental/packages/sdk-logs/src/LogRecordImpl.ts (updated)
  • experimental/packages/sdk-logs/test/common/LogRecord.test.ts (tests added)
  • experimental/packages/sdk-logs/test/common/utils.ts (updated for new behavior)

@Alec2435 Alec2435 requested a review from a team as a code owner June 25, 2025 19:58
Copy link

linux-foundation-easycla bot commented Jun 25, 2025

CLA Signed

The committers listed above are authorized under a signed CLA.

@dyladan
Copy link
Member

dyladan commented Jul 16, 2025

@JacksonWeber are your comments addressed?

This is required by spec so I expect it to be uncontroversial to get this merged soon.

@JacksonWeber
Copy link
Contributor

@JacksonWeber are your comments addressed?

This is required by spec so I expect it to be uncontroversial to get this merged soon.

Updated coverage looks good, however I don't seem to have the ability to resolve my comments.

@Alec2435
Copy link
Author

Sorry for not shooting an update with my updated commit, I think the test coverage should be pretty comprehensive now, hoping we can get this merged for proper spec compliance. I think I've resolved your comments @JacksonWeber

@dyladan
Copy link
Member

dyladan commented Jul 22, 2025

@JacksonWeber are your comments addressed?
This is required by spec so I expect it to be uncontroversial to get this merged soon.

Updated coverage looks good, however I don't seem to have the ability to resolve my comments.

An unfortunate reality of github. You need write permissions of some kind to resolve threads unfortunately. I think the PR author usually can do it though.

@dyladan
Copy link
Member

dyladan commented Jul 22, 2025

Do you think it would be reasonable to add the validation to the SDK? In general we try to keep as much logic in the SDK as possible in order to keep the API lightweight. Is there something in the spec that requires it in the API?

@Alec2435
Copy link
Author

Alec2435 commented Aug 4, 2025

@dyladan do you mean move the validation util to the sdk-logs package? Sure I can move it there, wasn't sure the best place to put it just saw the other type definitions were in api so thought it made sense to put the validation helper there.

@pichlermarc
Copy link
Member

@dyladan do you mean move the validation util to the sdk-logs package? Sure I can move it there, wasn't sure the best place to put it just saw the other type definitions were in api so thought it made sense to put the validation helper there.

@Alec2435 yes, the SDK packge is the best place to put this. We try to avoid having business logic in the api package if at all possible :)

export type { LogAttributes, LogBody, LogRecord } from './types/LogRecord';
export type { LoggerOptions } from './types/LoggerOptions';
export type { AnyValue, AnyValueMap } from './types/AnyValue';
export { isLogAttributeValue } from './utils/validation';
Copy link
Member

Choose a reason for hiding this comment

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

this is implementation code and should therefore go into sdk-logs instead of here. The API is mostly intended for just type definitions and registering the global, anything else should go into sdk-logs :)

@pichlermarc pichlermarc added this to the Logs API/SDK GA milestone Sep 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[sdk-logs, exporters] investigate if circular refrences are a problem during log record serialization

4 participants