deadtrickster / prometheus.ex

Prometheus.io Elixir client
411 stars 68 forks source link

Metrics declared via module attributes do not get registered #16

Closed seancribbs closed 6 years ago

seancribbs commented 6 years ago

I have been running into an issue where I declare metrics via module attributes like @counter and @histogram, but when running my test suite, failures occur because metrics the code attempts to update are not registered. I have worked around this by adding a loop like so to my application startup:

for mod <- Application.spec(:my_app)[:modules] do
  if function_exported?(mod, :__declare_prometheus_metrics__, 0) do
    mod.__declare_prometheus_metrics__()
  end
end

Obviously this workaround is brittle because it relies on knowledge of code generated by the macros in Prometheus.Metric. I'd like to stop using it.

The core problem is that the generated code calls Application.started_applications(), but normal OTP startup loads all application code before starting any applications. This means that the @on_load function will be called before prometheus has started and created its ets tables, and so no metrics will be declared and the function will never run when the application has already started.

Proposed solution: The macros should generate entries to be inserted into the default_metrics env key of the prometheus application. When the application starts, the default metrics are automatically declared. This will work because the application_controller process that owns the application environment table will be started at the time each user application is loaded.

Does that solution sound reasonable? If so, I will send a PR.