Skip to content

Add cloud.account.id resource attribute to language wrapper scripts#2157

Open
RaphaelManke wants to merge 5 commits intoopen-telemetry:mainfrom
RaphaelManke:add-cloud-account-id-resource-attribute
Open

Add cloud.account.id resource attribute to language wrapper scripts#2157
RaphaelManke wants to merge 5 commits intoopen-telemetry:mainfrom
RaphaelManke:add-cloud-account-id-resource-attribute

Conversation

@RaphaelManke
Copy link
Contributor

@RaphaelManke RaphaelManke commented Mar 7, 2026

Summary

  • Reads the AWS account ID from the /tmp/.otel-aws-account-id symlink (created by the collector extension during registration, see feat(lambda): write cloud.account.id symlink from extension #2127) in each language's wrapper script
  • Appends cloud.account.id as a resource attribute to OTEL_RESOURCE_ATTRIBUTES if not already set
  • Covers all languages: Node.js, Java (javaagent + wrapper), Python, and Ruby

How it works

┌─────────────────────────────────────────────────────────────────────┐
│                        Lambda Init Phase                            │
│                                                                     │
│  ┌──────────────────────────────────────────────────────────────┐   │
│  │  1. Collector Extension starts                               │   │
│  │     └─► Calls extensionClient.Register()                     │   │
│  │         └─► Receives AccountID in response                   │   │
│  │             └─► writeAccountIDSymlink()              (#2127) │   │
│  │                 Creates: /tmp/.otel-aws-account-id            │   │
│  │                          -> "123456789012" (symlink target)   │   │
│  └──────────────────────────────────────────────────────────────┘   │
│                              │                                      │
│                              ▼                                      │
│  ┌──────────────────────────────────────────────────────────────┐   │
│  │  2. Lambda Runtime starts                                    │   │
│  │     └─► AWS_LAMBDA_EXEC_WRAPPER invokes wrapper script       │   │
│  │         ┌────────────────────────────────────────────────┐   │   │
│  │         │  otel-handler / otel-instrument       (this PR)│   │   │
│  │         │                                                │   │   │
│  │         │  ACCOUNT_ID=$(readlink /tmp/.otel-aws-account-id)  │   │
│  │         │  export OTEL_RESOURCE_ATTRIBUTES=              │   │   │
│  │         │    "cloud.account.id=$ACCOUNT_ID,..."          │   │   │
│  │         └────────────────────────────────────────────────┘   │   │
│  │         └─► Language SDK initializes with resource attributes │   │
│  └──────────────────────────────────────────────────────────────┘   │
│                              │                                      │
│                              ▼                                      │
│  ┌──────────────────────────────────────────────────────────────┐   │
│  │  3. Function handler executes                                │   │
│  │     └─► All spans, logs, metrics from the SDKs include cloud.account.id    │   │
│  └──────────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────────┘

Key insight: The extension always registers before the runtime starts, so the symlink is guaranteed to exist by the time the wrapper script runs.

Motivation

The collector extension writes the AWS account ID as a symlink during registration (#2127). Since the language-specific wrapper scripts (otel-handler / otel-instrument) execute after the extension has registered, they can reliably read this symlink and propagate the account ID to the language SDKs via OTEL_RESOURCE_ATTRIBUTES.

This ensures cloud.account.id is present on all telemetry signals produced by the language SDKs without requiring users to manually configure it.

Test plan

  • Deploy Lambda with collector extension and verify cloud.account.id appears on spans/logs/metrics for each language runtime
  • Verify that if cloud.account.id is already set in OTEL_RESOURCE_ATTRIBUTES, it is not overwritten
  • Verify graceful degradation when symlink does not exist (error logged to stderr, execution continues)

Read the AWS account ID from the symlink written by the collector
extension during registration (/tmp/.otel-aws-account-id, introduced
in open-telemetry#2127) and append it as cloud.account.id to OTEL_RESOURCE_ATTRIBUTES
in the language-specific wrapper scripts.

This ensures the account ID is available as a resource attribute on
telemetry produced by the language SDKs (Node.js, Java, Python, Ruby),
since the wrapper scripts execute after the extension has registered
and created the symlink.
@RaphaelManke RaphaelManke requested a review from a team as a code owner March 7, 2026 17:23
Copy link
Member

@wpessers wpessers left a comment

Choose a reason for hiding this comment

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

Looks good 🚀 I'll be awaiting the results of your testing to make sure since you added the testing plan with open tasks to this PR.

@RaphaelManke
Copy link
Contributor Author

RaphaelManke commented Mar 7, 2026

Tested it and works as expected.
I also removed the error log as it would produce unnecessary messages when for example the lamguuage layer is used with and old or other collector and extended the README documenting the env vars from the wrapper script

@wpessers
Copy link
Member

wpessers commented Mar 7, 2026

the check-links action failure is unrelated to your pr, seems like the include-fragments config should now be include_fragments instead here:

include-fragments = true

I can fix it if you want, or if you'd rather do it yourself that's fine too. Up to you 😄

@wpessers
Copy link
Member

wpessers commented Mar 7, 2026

So if you prefer keeping the link to that pr in there, that's fine btw @RaphaelManke. It seems like it's just the changed config var name in lychee that is causing this to fail.

@RaphaelManke
Copy link
Contributor Author

No, its fine without the link 😃

fi

CLOUD_ACCOUNT_ID=$(readlink /tmp/.otel-aws-account-id 2>/dev/null || true)
if [ -n "$CLOUD_ACCOUNT_ID" ]; then
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a reason we are deviating from the strategy above for initializing the resource attributes? Generally, I think that the single if statement is a bit more readable.

Copy link
Member

@wpessers wpessers Mar 7, 2026

Choose a reason for hiding this comment

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

nice catch, agree

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.

3 participants