Skip to content

Add config.lambdakiq.metrics_enabled to turn off CloudWatch metrics - #42

Open
jeremiahlukus wants to merge 1 commit into
mainfrom
metrics-enabled-config
Open

Add config.lambdakiq.metrics_enabled to turn off CloudWatch metrics#42
jeremiahlukus wants to merge 1 commit into
mainfrom
metrics-enabled-config

Conversation

@jeremiahlukus

@jeremiahlukus jeremiahlukus commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Supersedes #38 by @fabiensebban, whose report and original patch this builds on.

Why

Lambdakiq emits CloudWatch Embedded Metrics for every ActiveJob event, dimensioned by AppName, JobEvent, and JobName. Custom metrics bill per unique dimension combination, so unique metric count scales as job classes × events × 3 metrics — at 50 job classes and 4 events that's ~600 custom metrics, roughly $180/month, plus per-job log ingestion. There was no way to opt out.

As reported in #38, the documented escape hatch didn't work either. Setting config.lambdakiq.metrics_logger = Logger.new("/dev/null") in config/application.rb had no effect, because the railtie's after_initialize hook reassigned metrics_logger unconditionally after application config was applied. Verified before the fix:

set in application.rb : #<Logger ... @logdev=nil>          # /dev/null
after initialize!     : #<ActiveSupport::BroadcastLogger>  # Rails.logger
CLOBBERED BY RAILTIE  : true

So metrics_logger= was documented but unsettable. That's fixed here too.

What changed

config.lambdakiq.metrics_enabled, defaulting to true — no behavior change for existing users.

The flag is checked in the notification subscriber rather than deep in the metric writer, so a disabled app skips ActiveSupport::Notifications::Event allocation and the entire instrument! payload build, not just the JSON.dump. It's checked again in Metrics.log so the class is safe called directly. Because the check is at call time rather than at subscribe time, the flag stays togglable at runtime.

metrics_logger boot-order fixafter_initialize now uses ||=, so it only fills in Rails.logger when the application hasn't chosen one. config.active_job.logger is deliberately left as a plain assignment; ActiveJob sets its own default, so ||= there would silently change behavior.

Test isolationLambdakiq.config is a process-wide OrderedOptions, so a test that mutates it leaks into every test after it. On #38's version I confirmed that when its new test fails, the leaked false takes 3 unrelated tests down with it. Config is now reset in the global before block.

Naming

Named metrics_enabled rather than #38's send_cloud_watch_metrics to match the existing metrics_namespace / metrics_logger / metrics_app_name family. Nothing was released under the old name, so there's no compatibility shim.

Docs

Documents metrics_enabled=, plus metrics_app_name= which already existed but was undocumented, and adds a section covering both ways to reduce metric cost. It also notes that metric properties include each job's arguments — an independent reason some apps will want this off.

Testing

42 runs, 260 assertions, 0 failures, stable across repeated runs.

New test/cases/railtie_test.rb boots a throwaway Rails app in a subprocess, since Rails initializes only once per process and the existing dummy app is already booted — the boot-order bug is otherwise untestable in-suite.

I verified each guard is load-bearing by reverting them individually against the new tests:

  • reverting metrics_logger ||=does not overwrite a metrics_logger set by the application fails
  • removing the metrics_enabled guards → does not log cloudwatch embedded metrics when metrics are disabled fails

CloudWatch Embedded Metrics are emitted for every ActiveJob event and
dimensioned by AppName, JobEvent and JobName. Since custom metrics bill per
unique dimension combination, apps with many job classes or high job volume
can run up real CloudWatch cost with no way to opt out.

Adds `config.lambdakiq.metrics_enabled`, defaulting to true so behavior is
unchanged. The flag is checked in the notification subscriber so that a
disabled app does not allocate an Event or build any metric payload, and
again in Metrics.log so the class is safe to call directly.

Also fixes `metrics_logger=`, which was documented but impossible to set: the
railtie's after_initialize hook assigned it unconditionally, clobbering any
value the application set in config/application.rb. It now only fills in
Rails.logger when the application has not chosen a logger.

Tests reset Lambdakiq.config between runs, since it is a process wide
OrderedOptions and a leaked value would cascade into unrelated tests.

Co-authored-by: fabiensebban <fa.sebban@gmail.com>
@jeremiahlukus

Copy link
Copy Markdown
Contributor Author

@metaskills Hey do you mind adding fixing up the publish gem workflow? https://github.com/rails-lambda/lambdakiq/actions/runs/26990002969/job/79647930370

[Push gem to RubyGems.org](https://github.com/rails-lambda/lambdakiq/actions/runs/26990002969/job/79647930370#step:4:47)
No trusted publisher configured for this workflow found on https://rubygems.org for audience rubygems.org

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