Skip to content

Wire resource attributes into Beholder ChipIngress emitters#2216

Open
pkcll wants to merge 8 commits into
mainfrom
chip-ingress-resource-attributes
Open

Wire resource attributes into Beholder ChipIngress emitters#2216
pkcll wants to merge 8 commits into
mainfrom
chip-ingress-resource-attributes

Conversation

@pkcll

@pkcll pkcll commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Summary

Wire node resource attributes from beholder.Config.ResourceAttributes into the ChipIngress batch and sync emitters via CloudEvent extensions, so they reach the cre topic as ce_<sanitized> Kafka headers.

Changes

  • pkg/beholder/batch_emitter_service.go: store resource attributes and stamp them on each emitted event via chipingress.WithResourceAttributeExtensions.
  • pkg/beholder/chip_ingress_emitter.go: same for the sync emitter.
  • pkg/beholder/client.go: pass resource attributes into the ChipIngress client header provider.
  • pkg/beholder/resource_attributes.go: add resourceAttributesToStringMap helper.
  • Root go.mod: bump pkg/chipingress to the resource-attributes branch (Add resource attribute support to ChipIngress client #2267).

Related PRs

Test plan

  • go test ./pkg/beholder/...

Notes

  • The previous Co-authored-by: Cursor attribution has been removed from the commit history.
  • gRPC metadata → Kafka header forwarding is unconfirmed on the chip-ingress server side; the CE-extension path guarantees ce_<name> headers immediately.
  • pkg/durableemitter remains out of scope.

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

✅ API Diff Results - github.com/smartcontractkit/chainlink-common/pkg/chipingress

✅ Compatible Changes (7)

./ (7)
  • EventOpt — ➕ Added

  • NewEventWithOpts — ➕ Added

  • NewStaticHeaderProvider — ➕ Added

  • SanitizeExtensionName — ➕ Added

  • SanitizeMetadataHeaders — ➕ Added

  • SanitizeMetadataValue — ➕ Added

  • WithResourceAttributeExtensions — ➕ Added


📄 View full apidiff report

@pkcll
pkcll force-pushed the chip-ingress-resource-attributes branch from e6eabcc to fdb6dee Compare July 2, 2026 03:48
@pkcll
pkcll requested a review from patrickhuie19 July 2, 2026 05:05
@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

✅ API Diff Results - github.com/smartcontractkit/chainlink-common

✅ Compatible Changes (1)

pkg/beholder.ChipIngressEmitterConfig (1)
  • NewWithResourceAttributes — ➕ Added

📄 View full apidiff report

Comment thread go.mod Outdated
gopkg.in/yaml.v2 v2.4.0 // indirect
)

replace github.com/smartcontractkit/chainlink-common/pkg/chipingress => ./pkg/chipingress

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.

any way to avoid the local replace?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

For sure, will clean this up.

patrickhuie19
patrickhuie19 previously approved these changes Jul 10, 2026
@pkcll
pkcll force-pushed the chip-ingress-resource-attributes branch 5 times, most recently from aa6b73c to d6a531b Compare July 11, 2026 01:32
@engnke

engnke commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

overall approach lgtm. Adding the CloudEvent extensions as the guaranteed propagation path makes sense, and we're keeping the gRPC header route for observability is reasonable

@pkcll
pkcll force-pushed the chip-ingress-resource-attributes branch 2 times, most recently from 2a6fa46 to 3ebb388 Compare July 13, 2026 21:12
pkcll added a commit to smartcontractkit/chainlink that referenced this pull request Jul 13, 2026
Pick up chip-ingress resource attribute propagation from
smartcontractkit/chainlink-common#2216.

Co-authored-by: Cursor <cursoragent@cursor.com>
@pkcll
pkcll force-pushed the chip-ingress-resource-attributes branch 2 times, most recently from e7e82a2 to 1f79a15 Compare July 13, 2026 21:14
pkcll added a commit to smartcontractkit/chainlink that referenced this pull request Jul 13, 2026
Pick up chip-ingress resource attribute propagation from
smartcontractkit/chainlink-common#2216.

Co-authored-by: Cursor <cursoragent@cursor.com>
pkcll added a commit to smartcontractkit/chainlink that referenced this pull request Jul 13, 2026
Pick up chip-ingress resource attribute propagation from
smartcontractkit/chainlink-common#2216.

Co-authored-by: Cursor <cursoragent@cursor.com>
@pkcll
pkcll force-pushed the chip-ingress-resource-attributes branch from 1f79a15 to e1e0648 Compare July 20, 2026 23:48
pkcll added a commit to smartcontractkit/chainlink that referenced this pull request Jul 20, 2026
@pkcll
pkcll force-pushed the chip-ingress-resource-attributes branch 3 times, most recently from f5eda78 to 0a22a31 Compare July 21, 2026 05:25
pkcll added a commit to smartcontractkit/chainlink that referenced this pull request Jul 21, 2026
pkcll added a commit to smartcontractkit/chainlink that referenced this pull request Jul 21, 2026
@pkcll

pkcll commented Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

Split into two PRs:

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 8 out of 9 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (1)

pkg/beholder/chip_ingress_emitter.go:64

  • NewWithResourceAttributes stores the caller-provided map[string]string directly. Because maps are reference types, a caller could mutate the map after construction (or share it across goroutines), leading to data races or non-deterministic extensions. Copy the map before storing it internally.
	var resourceAttrs *resourceAttrExtensions
	if len(attrs) > 0 {
		resourceAttrs = &resourceAttrExtensions{attrs: attrs}
	}

Comment on lines 20 to 26
type ChipIngressBatchEmitterService struct {
services.Service
eng *services.Engine

batchClient *batch.Client
batchClient *batch.Client
resourceAttrs map[string]string

Comment on lines 88 to 92
e := &ChipIngressBatchEmitterService{
batchClient: batchClient,
metrics: metrics,
batchClient: batchClient,
resourceAttrs: resourceAttributesToStringMap(cfg.ResourceAttributes),
metrics: metrics,
}
Comment on lines 140 to 145
attributes := newAttributes(attrKVs...)

event, err := chipingress.NewEvent(domain, entity, body, attributes)
event, err := chipingress.NewEventWithOpts(domain, entity, body, attributes, chipingress.WithResourceAttributeExtensions(e.resourceAttrs))
if err != nil {
return fmt.Errorf("failed to create CloudEvent: %w", err)
}
Copilot AI review requested due to automatic review settings July 22, 2026 05:56

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 8 out of 9 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

pkg/beholder/chip_ingress_emitter.go:64

  • NewWithResourceAttributes stores the provided attrs map directly. Because Emit can be called concurrently, any external mutation of the map after construction could cause a data race (and surprising behavior). Consider defensively cloning the map before storing it in the emitter.
	var resourceAttrs *resourceAttrExtensions
	if len(attrs) > 0 {
		resourceAttrs = &resourceAttrExtensions{attrs: attrs}
	}

@pkcll
pkcll marked this pull request as ready for review July 22, 2026 06:08
@pkcll
pkcll requested review from a team as code owners July 22, 2026 06:08
thomaska
thomaska previously approved these changes Jul 22, 2026
Copilot AI review requested due to automatic review settings July 22, 2026 16:19

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 8 out of 9 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (2)

pkg/beholder/batch_emitter_service.go:26

  • ChipIngressBatchEmitterService is an exported struct type; adding a map[string]string field makes the type non-comparable, which can be an API-breaking change (similar to the concern noted in chip_ingress_emitter.go). Consider storing resource attributes behind a pointer wrapper (or another comparable container) to preserve type comparability, and only dereference it when stamping extensions.
type ChipIngressBatchEmitterService struct {
	services.Service
	eng *services.Engine

	batchClient   *batch.Client
	resourceAttrs map[string]string

pkg/beholder/chip_ingress_emitter.go:64

  • NewWithResourceAttributes stores the caller-provided attrs map directly. Because maps are mutable and not concurrency-safe, a caller mutating the map after construction (or concurrently with Emit) can cause data races or panics. Defensive-copy the map on entry before storing it on the emitter.
	var resourceAttrs *resourceAttrExtensions
	if len(attrs) > 0 {
		resourceAttrs = &resourceAttrExtensions{attrs: attrs}
	}

Copilot AI review requested due to automatic review settings July 22, 2026 16:24

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 8 out of 9 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (2)

pkg/beholder/chip_ingress_emitter.go:64

  • NewWithResourceAttributes stores the passed-in attrs map directly. Because maps are reference types, callers can mutate it after construction (or concurrently), which can change emitted events and potentially introduce data races. Consider defensively copying the map before storing it on the emitter.
	var resourceAttrs *resourceAttrExtensions
	if len(attrs) > 0 {
		resourceAttrs = &resourceAttrExtensions{attrs: attrs}
	}

pkg/beholder/batch_emitter_service.go:150

  • emitInternal always uses NewEventWithOpts + WithResourceAttributeExtensions, even when no resource attributes are configured (resourceAttrs is an empty map). This adds overhead on every event and may inadvertently change behavior vs the previous NewEvent path. Consider only applying the opt when resourceAttrs is non-empty (mirroring ChipIngressEmitter.Emit).
		attributes := newAttributes(attrKVs...)

		event, err := chipingress.NewEventWithOpts(domain, entity, body, attributes, chipingress.WithResourceAttributeExtensions(e.resourceAttrs))
		if err != nil {
			return fmt.Errorf("failed to create CloudEvent: %w", err)
		}

Copilot AI review requested due to automatic review settings July 22, 2026 16:28

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 8 out of 9 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

pkg/beholder/chip_ingress_emitter.go:64

  • NewWithResourceAttributes stores the caller-provided attrs map directly on the emitter. If the caller later mutates that map (or shares it across goroutines), emits can race on concurrent map reads/writes. Since these attributes are meant to be static config, defensively clone the map before storing it.
	var resourceAttrs *resourceAttrExtensions
	if len(attrs) > 0 {
		resourceAttrs = &resourceAttrExtensions{attrs: attrs}
	}

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.

5 participants