Module: Ask::Observability
- Defined in:
- lib/ask/observability.rb,
lib/ask/observability/metrics.rb,
lib/ask/observability/railtie.rb,
lib/ask/observability/version.rb,
lib/ask/observability/bootstrap.rb,
lib/ask/observability/subscriber.rb,
lib/ask/observability/metrics_app.rb,
lib/ask/observability/configuration.rb,
lib/generators/ask/observability/install_generator.rb
Overview
Ask::Observability — Prometheus metrics, OpenTelemetry bootstrap, and structured logging for the ask-rb ecosystem.
The ask-rb observability story composes:
* ask-instrumentation — emits events for every LLM operation
* ask-opentelemetry — events → OpenTelemetry spans
* ask-observability — events → Prometheus metrics, plus the
OTel/logging bootstrap and /metrics
* ask-monitoring — events → in-app dashboard + alerts
Usage
Ask::Observability.install
In a Rails app the railtie auto-installs (bootstrap + subscriber + /metrics); configure it first:
Ask::Observability.configure do |config|
config.service_name = "my-app"
config. = [:workspace_id]
end
Defined Under Namespace
Modules: Bootstrap Classes: Configuration, InstallGenerator, Metrics, MetricsApp, Railtie, Subscriber
Constant Summary collapse
- VERSION =
'0.1.2'
Class Attribute Summary collapse
-
.registry ⇒ Prometheus::Client::Registry
The Prometheus registry backing every metric (and the /metrics endpoint).
Class Method Summary collapse
-
.config ⇒ Configuration
The process-wide configuration.
- .configure {|Configuration| ... } ⇒ Object
-
.counter(name, **kwargs) ⇒ Prometheus::Client::Counter
Register-or-resolve a counter on the shared registry.
-
.histogram(name, **kwargs) ⇒ Prometheus::Client::Histogram
Register-or-resolve a histogram (see #counter).
-
.install ⇒ Object
Subscribe to every ask-instrumentation event and start maintaining Prometheus metrics.
-
.installed? ⇒ Boolean
Whether the subscriber is installed.
-
.metrics ⇒ Metrics
The metric definitions for the current registry.
-
.uninstall ⇒ Object
Remove the subscriber (tests use this to keep suites isolated).
-
.with_context(metadata) { ... } ⇒ Object
Wrap a block so the given metadata flows into ask-instrumentation events (and thus into spans and metrics) AND into Rails log lines as tags, when Rails is present.
Class Attribute Details
.registry ⇒ Prometheus::Client::Registry
The Prometheus registry backing every metric (and the /metrics endpoint). Tests inject a fresh registry to isolate state.
62 63 64 |
# File 'lib/ask/observability.rb', line 62 def registry @registry ||= Prometheus::Client::Registry.new end |
Class Method Details
.config ⇒ Configuration
The process-wide configuration. Configure before install (or before the railtie runs) so metrics carry the final label set.
49 50 51 |
# File 'lib/ask/observability.rb', line 49 def config @config ||= Configuration.new end |
.configure {|Configuration| ... } ⇒ Object
54 55 56 |
# File 'lib/ask/observability.rb', line 54 def configure yield config end |
.counter(name, **kwargs) ⇒ Prometheus::Client::Counter
Register-or-resolve a counter on the shared registry. Reload-safe: in development, Zeitwerk re-evaluates app files that register metrics, which would re-register the same name against a registry that still holds it and raise AlreadyRegisteredError (surfacing as a 500 in the app). Resolving the existing metric keeps registrations idempotent instead.
77 78 79 80 81 |
# File 'lib/ask/observability.rb', line 77 def counter(name, **kwargs) registry.get(name) || registry.counter(name, **kwargs) rescue Prometheus::Client::Registry::AlreadyRegisteredError registry.get(name) end |
.histogram(name, **kwargs) ⇒ Prometheus::Client::Histogram
Register-or-resolve a histogram (see #counter).
86 87 88 89 90 |
# File 'lib/ask/observability.rb', line 86 def histogram(name, **kwargs) registry.get(name) || registry.histogram(name, **kwargs) rescue Prometheus::Client::Registry::AlreadyRegisteredError registry.get(name) end |
.install ⇒ Object
Subscribe to every ask-instrumentation event and start maintaining Prometheus metrics. Idempotent — subsequent calls are no-ops.
94 95 96 97 98 99 100 |
# File 'lib/ask/observability.rb', line 94 def install return if installed? return if config.enabled == false @subscriber = Ask::Instrumentation.subscribe(/\.ask$/, Subscriber.new) @installed = true end |
.installed? ⇒ Boolean
Returns whether the subscriber is installed.
112 113 114 |
# File 'lib/ask/observability.rb', line 112 def installed? !!@installed end |
.metrics ⇒ Metrics
The metric definitions for the current registry.
137 138 139 |
# File 'lib/ask/observability.rb', line 137 def metrics Metrics.for(registry, metadata_label_keys: config.) end |
.uninstall ⇒ Object
Remove the subscriber (tests use this to keep suites isolated).
103 104 105 106 107 108 109 |
# File 'lib/ask/observability.rb', line 103 def uninstall return unless @subscriber Ask::Instrumentation.unsubscribe(@subscriber) @subscriber = nil @installed = false end |
.with_context(metadata) { ... } ⇒ Object
Wrap a block so the given metadata flows into ask-instrumentation events (and thus into spans and metrics) AND into Rails log lines as tags, when Rails is present. One call to correlate a unit of work — a request, a job, a call — everywhere.
124 125 126 127 128 129 130 131 132 |
# File 'lib/ask/observability.rb', line 124 def with_context(, &block) Ask::Instrumentation.() do if defined?(::Rails) && ::Rails.respond_to?(:logger) && ::Rails.logger.respond_to?(:tagged) ::Rails.logger.tagged(**, &block) else yield end end end |