Skip to content

feat(agent): enable service.profilesSupport feature gate by default - #2277

Closed
OisinMcMenamin wants to merge 1 commit into
aws:mainfrom
OisinMcMenamin:feat/enable-profiles-support-gate
Closed

feat(agent): enable service.profilesSupport feature gate by default#2277
OisinMcMenamin wants to merge 1 commit into
aws:mainfrom
OisinMcMenamin:feat/enable-profiles-support-gate

Conversation

@OisinMcMenamin

Copy link
Copy Markdown

Description of the issue

Issue: #2273
Supersedes #2274 (same change; re-raised from this fork so the work can continue to be driven to completion — the original author's commit and attribution are preserved).

Configuring a profiles pipeline makes the agent fail to start, because the
collector's profiles signal is gated behind service.profilesSupport (alpha, off
by default in collector v0.124.0):

pipeline "profiles": profiling signal support is at alpha level, gated under the "service.profilesSupport" feature gate

The agent builds the collector's arguments itself and only ever passes
--config=, so an operator has no supported way to enable the gate.

Description of changes

The agent now appends --feature-gates=+service.profilesSupport to the arguments
it builds for the collector command, so profiles pipelines start without the
operator needing to know the gate exists.

The flag is only appended after checking the collector's feature-gate registry
for an enableable gate with that ID. featuregate.Registry.Set returns an error
for an unknown gate ID, which surfaces as a flag-parse failure and a fatal
startup error. Without the guard, the moment the gate graduates and is deleted
upstream, a routine collector dependency bump would produce an agent that
refuses to start. With it, graduation is a no-op.

The guard also treats StageDeprecated as not enableable, because Set rejects
enabling a deprecated gate with the same class of error, and deprecated is the
pre-deletion state of a graduating gate. A StageStable gate that is still
registered remains enableable, so the flag keeps being passed until the gate is
removed from the registry entirely.

New file cmd/amazon-cloudwatch-agent/featuregates.go holds
collectorFeatureGateArgs and the registry check. amazon-cloudwatch-agent.go
gains one line at the existing cmd.SetArgs site. featuregate moves from the
indirect to the direct require block in go.mod (no version change).

License

By submitting this pull request, I confirm that you can use, modify, copy, and
redistribute this contribution, under the terms of your choice.

Tests

New unit tests in cmd/amazon-cloudwatch-agent/featuregates_test.go cover all
four registry states: gate registered at alpha (flag passed), gate at stable
(flag still passed), gate absent (no flag, no error), and gate deprecated (no
flag, no error).

Rather than string-comparing the produced arguments, each case parses them
through a real featuregate registry flag set, and a separate test asserts the
gate actually flips to enabled — so the tests validate the flag name and +
syntax against the library rather than against a hardcoded expectation.

  • go build ./... — pass
  • CGO_ENABLED=0 go test ./... — pass (full suite)
  • make fmt / make fmt-sh — clean

Checklist

  • Commits are squashed into a logical, reviewable set (one commit for a single change)
  • Commits and PR description comply with Amazon internal guidelines
  • make passes locally (build, unit tests, lint) — make lint reports pre-existing repo-wide findings that also fail on unmodified main; none are in the new file or on the two modified lines
  • All GitHub Actions checks on the PR are passing (pending CI approval/run)
  • Integration test evidence: N/A — the change is behaviorally inert for all currently-expressible configurations: no profiles pipeline can be produced by the config translator yet, so the only observable difference is the extra --feature-gates argument, which is fully covered by unit tests. End-to-end profiles evidence lands with the config-translator follow-up PR.
  • New or updated integration test coverage: N/A — same reason; integration coverage arrives with the translator PR that makes profiles configurable.
  • New functionality has unit tests; bug fixes have a reproducing test
  • Config translation changes include updated golden files — N/A, no translator changes
  • Breaking or customer-visible changes are called out in the PR description — none; existing configurations see no behavior change

Profiles pipelines are gated behind the collector's alpha
service.profilesSupport feature gate, so a profiles pipeline currently fails
agent startup outright:

    pipeline "profiles": profiling signal support is at alpha level, gated
    under the "service.profilesSupport" feature gate

The agent builds the collector's argv itself and only passes --config, so an
operator has no supported way to enable the gate. It now requests the gate
when building those args, which is what makes profiles usable out of the box.

The request is guarded by a lookup in the collector's feature gate registry.
featuregate.Registry.Set rejects an unknown gate ID (and rejects enabling a
deprecated one), and that error surfaces as a cobra flag parse failure, i.e.
a fatal startup error. Since this gate is on a graduation path and will
eventually be deleted upstream, passing it unconditionally would turn a
routine collector dependency bump into an agent that refuses to start.
Consulting the registry first makes graduation a no-op instead.

Key files:
- cmd/amazon-cloudwatch-agent/featuregates.go: collectorFeatureGateArgs
  builds the --feature-gates arg, skipping any gate the registry cannot
  enable.
- cmd/amazon-cloudwatch-agent/amazon-cloudwatch-agent.go: appends those args
  alongside the existing --config args in runAgent.

Testing:
- New unit tests cover all four registry states: gate registered (arg
  emitted), absent (nil, no error), stable (still enableable, arg emitted),
  and deprecated (treated like absent). The produced args are parsed through
  the real featuregate flag set rather than string-compared, and one test
  asserts the gate ends up enabled after parsing.
- go build ./..., CGO_ENABLED=0 go test ./cmd/amazon-cloudwatch-agent/,
  make fmt and make fmt-sh all pass.

Closes aws#2273
@OisinMcMenamin
OisinMcMenamin requested a review from a team as a code owner September 7, 2026 15:10
OisinMcMenamin pushed a commit to OisinMcMenamin/amazon-cloudwatch-agent that referenced this pull request Sep 8, 2026
A profiles section in amazon-cloudwatch-agent.json now generates a complete
OTel profiles pipeline: an otlp receiver (HTTP, default 127.0.0.1:4318), a
resource processor that upserts service.name, and an otlp_http exporter that
sends gzip-compressed, SigV4-signed profiles to
https://monitoring.{region}.{partition-dns-suffix}/v1development/profiles
(or endpoint_override, a host override with the profiles path preserved).
Export auth goes through the agenthealth extension wrapping a sigv4auth
extension configured with service monitoring, matching the other CloudWatch
OTLP exporters.

The translator enables the service.profilesSupport feature gate in its own
process so the generated config passes translation-time service validation.
The collector runtime enables the gate separately at startup (aws#2277); that
change must merge before, or ship in the same release as, this one -- without
it the runtime collector rejects a generated profiles pipeline at startup.

Profiles is an alpha signal with limited processor support, so the generated
pipeline stays minimal by construction: the batch processor is never added
(it does not support profiles and fails collector startup), and service.name
is always stamped (unstamped profiles are filed under unknown).

Example configuration:

    {
      "agent": { "region": "us-east-1" },
      "profiles": {
        "service_name": "my-service",
        "otlp": { "http_endpoint": "127.0.0.1:4318" }
      }
    }

service_name is required; missing or blank values and unknown fields fail
schema validation. Region resolution and credentials come from the agent
section as with the other signals.
@OisinMcMenamin

Copy link
Copy Markdown
Author

Closing in favor of #2274 — the original PR for this change by the commit's author, where review will continue. Same commit, same content; this was raised while we sorted out ownership of the work.

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.

1 participant