chronos-ruby 0.7.0.pre.1 → 0.8.0.pre.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +24 -0
- data/README.md +33 -9
- data/contracts/apm-batch-v1.schema.json +1 -1
- data/contracts/dependencies-v1.schema.json +38 -0
- data/contracts/event-v1.schema.json +1 -1
- data/docs/adr/ADR-016-explicit-observability-integrations.md +25 -0
- data/docs/architecture.md +6 -1
- data/docs/compatibility.md +2 -0
- data/docs/configuration.md +12 -2
- data/docs/data-collected.md +9 -4
- data/docs/examples/plain-ruby.md +7 -1
- data/docs/modules/apm-aggregation.md +2 -2
- data/docs/modules/cache-observability.md +16 -0
- data/docs/modules/configuration.md +2 -0
- data/docs/modules/dependencies.md +18 -0
- data/docs/modules/external-http.md +27 -0
- data/docs/modules/rails-legacy.md +1 -1
- data/docs/modules/sidekiq-legacy.md +1 -1
- data/docs/modules/telemetry-events.md +2 -2
- data/docs/performance.md +16 -1
- data/docs/privacy-lgpd.md +11 -2
- data/docs/troubleshooting.md +13 -1
- data/lib/chronos/agent.rb +24 -0
- data/lib/chronos/application/apm_aggregator.rb +7 -10
- data/lib/chronos/application/apm_error_classifier.rb +27 -0
- data/lib/chronos/application/capture_telemetry.rb +1 -1
- data/lib/chronos/application/dependency_reporter.rb +129 -0
- data/lib/chronos/application/remote_configuration.rb +3 -1
- data/lib/chronos/configuration/apm_validation.rb +17 -1
- data/lib/chronos/configuration.rb +15 -2
- data/lib/chronos/core/cache_normalizer.rb +99 -0
- data/lib/chronos/core/telemetry_event.rb +1 -1
- data/lib/chronos/integrations/net_http.rb +165 -0
- data/lib/chronos/net_http.rb +4 -0
- data/lib/chronos/observability_facade.rb +43 -0
- data/lib/chronos/rails/notifications_subscriber.rb +6 -5
- data/lib/chronos/version.rb +1 -1
- data/lib/chronos.rb +6 -0
- metadata +12 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 44c7cad424497d7998727de5a916594ecc3ce9dfda7580376fe4a754edd9096e
|
|
4
|
+
data.tar.gz: 3f7a64cbf5b5879e107d7102c1f72cdd2ac4c941e1640a05b6210db79cd948f9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f62fa57bfcfec70f7172afc4c939d905aa9c7d9215960b73fa0c54406568b43b93e41b02ba22eb13b381243e06cf61a087544db00ed97ea4ce5805f84e9901e7
|
|
7
|
+
data.tar.gz: 3a66ec4e2a85f7f2e79868523fe63a493aeb598aff810dfd21b84a25dd0505e21ee66cac35a7113927a9b4b5a5c5ea2f41d25b89b452b38088c0ef3570f876bf
|
data/CHANGELOG.md
CHANGED
|
@@ -12,6 +12,30 @@ All notable changes are documented here. The project follows Semantic Versioning
|
|
|
12
12
|
- legacy CI now resolves Bundler 1.17.3 through `Gem.bin_path` on RubyGems versions that do not support the `_version_` executable selector.
|
|
13
13
|
- documentation verification now reads source and Markdown files explicitly as UTF-8 on legacy container locales.
|
|
14
14
|
|
|
15
|
+
## [0.8.0.pre.1] - 2026-07-20
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- optional per-instance `Net::HTTP` instrumentation with sanitized host, method, status, duration, timeout and connection-error classification;
|
|
20
|
+
- outbound trace/request header propagation without collecting URLs, Authorization, request bodies, response bodies, or error messages;
|
|
21
|
+
- external HTTP metric aggregation and traced-request `external_http` breakdown;
|
|
22
|
+
- cache operation, duration, hit/miss, backend, namespace, and opt-in project-scoped SHA-256 key identity;
|
|
23
|
+
- bounded dependency inventory containing loaded gem versions, Ruby, optional Rails/web server/database/Sidekiq detection, and configured release;
|
|
24
|
+
- version 0.8 configuration, contracts, tests, executable example, benchmark, module documentation, and ADR-016.
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
|
|
28
|
+
- dependency inventory is queued at most once per configured agent instead of being attached to every exception;
|
|
29
|
+
- cache notification fields now use bounded backend/namespace/outcome names and omit raw keys by default;
|
|
30
|
+
- version advanced to `0.8.0.pre.1`.
|
|
31
|
+
|
|
32
|
+
### Known limitations
|
|
33
|
+
|
|
34
|
+
- outbound HTTP instrumentation must be enabled and installed on each selected `Net::HTTP` instance;
|
|
35
|
+
- Faraday, HTTP.rb, Excon, and RestClient adapters are not included;
|
|
36
|
+
- cache key hashing is opt-in and low-entropy keys may remain guessable;
|
|
37
|
+
- dependency detection uses already loaded gems and does not open a database connection or inspect lockfiles.
|
|
38
|
+
|
|
15
39
|
## [0.7.0.pre.1] - 2026-07-20
|
|
16
40
|
|
|
17
41
|
### Added
|
data/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Chronos Ruby
|
|
2
2
|
|
|
3
|
-
Chronos Ruby is the framework-independent client for sending Ruby application errors and bounded telemetry to Chronos. Version 0.
|
|
3
|
+
Chronos Ruby is the framework-independent client for sending Ruby application errors and bounded telemetry to Chronos. Version 0.8 adds optional per-instance outbound `Net::HTTP` timing, privacy-safe cache identity, and one bounded dependency inventory per agent.
|
|
4
4
|
|
|
5
5
|
## What the gem collects
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Version 0.8 can collect:
|
|
8
8
|
|
|
9
9
|
- exception class, message, structured backtrace, and chained causes;
|
|
10
10
|
- timestamp, severity, tags, and an optional fingerprint;
|
|
@@ -18,7 +18,7 @@ See [Data collected](docs/data-collected.md) for the complete field table.
|
|
|
18
18
|
|
|
19
19
|
## What is not collected by default
|
|
20
20
|
|
|
21
|
-
Chronos Ruby does not inspect environment variables, request bodies, cookies,
|
|
21
|
+
Chronos Ruby does not inspect environment variables, request/response bodies, cookies, Authorization headers, source code, database contents, lockfiles, or gem paths. Dependency reporting reads only already loaded gem names and versions once per agent. Application-supplied fields are recursively sanitized, but applications should still avoid sending unnecessary personal, health, financial, or authentication data.
|
|
22
22
|
|
|
23
23
|
## Supported Ruby and Rails versions
|
|
24
24
|
|
|
@@ -31,7 +31,7 @@ See [Compatibility](docs/compatibility.md).
|
|
|
31
31
|
The current public build is a pre-release. Add its exact version to the application's `Gemfile`:
|
|
32
32
|
|
|
33
33
|
```ruby
|
|
34
|
-
gem "chronos-ruby", "0.
|
|
34
|
+
gem "chronos-ruby", "0.8.0.pre.1"
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
Install with a Bundler version compatible with the application. For the oldest supported runtime:
|
|
@@ -52,7 +52,7 @@ gem install chronos-ruby --pre
|
|
|
52
52
|
Version 0.5 exposes Rails support explicitly, keeping Rails and ActiveSupport out of plain Ruby applications:
|
|
53
53
|
|
|
54
54
|
```ruby
|
|
55
|
-
gem "chronos-ruby", "0.
|
|
55
|
+
gem "chronos-ruby", "0.8.0.pre.1", :require => "chronos/rails"
|
|
56
56
|
```
|
|
57
57
|
|
|
58
58
|
Generate the initializer with:
|
|
@@ -191,16 +191,36 @@ Version `0.6.0.pre.1` adds optional Sidekiq 4/5 middleware:
|
|
|
191
191
|
|
|
192
192
|
```ruby
|
|
193
193
|
gem "sidekiq", "~> 5.0"
|
|
194
|
-
gem "chronos-ruby", "0.
|
|
194
|
+
gem "chronos-ruby", "0.8.0.pre.1", :require => "chronos/sidekiq"
|
|
195
195
|
```
|
|
196
196
|
|
|
197
197
|
The client middleware propagates only trace/request identifiers in a versioned Sidekiq-envelope field and never changes worker arguments. The server records class, queue, JID, retry count, duration, calculable queue latency, bounded arguments/tags, status, and error class. Values pass through the shared sanitizer before delivery. Failed jobs are notified once and the original exception is re-raised. See [Sidekiq 4/5 legacy integration](docs/modules/sidekiq-legacy.md).
|
|
198
198
|
|
|
199
199
|
The Rails subscriber continues to record basic Active Job class, queue, and duration. Full Active Job context propagation plus optional Resque and Delayed Job adapters are subsequent version 0.6 increments.
|
|
200
200
|
|
|
201
|
+
## External HTTP, cache, and dependencies
|
|
202
|
+
|
|
203
|
+
Version 0.8 instruments only explicitly selected `Net::HTTP` connection objects, avoiding a global monkey patch:
|
|
204
|
+
|
|
205
|
+
```ruby
|
|
206
|
+
Chronos.configure do |config|
|
|
207
|
+
# required connection settings omitted
|
|
208
|
+
config.external_http_enabled = true
|
|
209
|
+
config.external_http_trace_headers = true
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
http = Net::HTTP.new("payments.example.com", 443)
|
|
213
|
+
http.use_ssl = true
|
|
214
|
+
Chronos.instrument_net_http(http)
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
The wrapper records only sanitized host, method, status, duration, timeout, connection-error flag, and error class. It propagates `X-Chronos-Trace-ID` and `X-Chronos-Request-ID` when available and never reads URL path/query, Authorization, request body, response body, or error message.
|
|
218
|
+
|
|
219
|
+
Rails cache telemetry omits raw keys by default. Set `cache_key_mode = :sha256` to emit a project-scoped hash; `:none` is the default. Dependency reporting is enabled by default, reads at most 100 already loaded gem specs, and emits one independent `dependencies` event per agent. Set `dependency_reporting = false` to disable it. See [External HTTP](docs/modules/external-http.md), [Cache observability](docs/modules/cache-observability.md), and [Dependency inventory](docs/modules/dependencies.md).
|
|
220
|
+
|
|
201
221
|
## Deploy tracking
|
|
202
222
|
|
|
203
|
-
Deploy notifications are not implemented in version 0.
|
|
223
|
+
Deploy notifications are not implemented in version 0.8. `app_version` is included in event service metadata and the once-per-agent dependency inventory for release correlation.
|
|
204
224
|
|
|
205
225
|
## Asynchronous queue
|
|
206
226
|
|
|
@@ -273,6 +293,9 @@ Chronos.configure do |config|
|
|
|
273
293
|
config.apm_enabled = true
|
|
274
294
|
config.apm_max_groups = 200
|
|
275
295
|
config.apm_flush_count = 100
|
|
296
|
+
config.external_http_enabled = false
|
|
297
|
+
config.cache_key_mode = :none
|
|
298
|
+
config.dependency_reporting = true
|
|
276
299
|
end
|
|
277
300
|
```
|
|
278
301
|
|
|
@@ -284,7 +307,7 @@ Configuration errors are raised during `Chronos.configure`. Capture and delivery
|
|
|
284
307
|
|
|
285
308
|
## Benchmark
|
|
286
309
|
|
|
287
|
-
Run the version 0.
|
|
310
|
+
Run the version 0.8 benchmarks with:
|
|
288
311
|
|
|
289
312
|
```bash
|
|
290
313
|
bundle _1.17.3_ exec ruby benchmarks/capture_exception.rb
|
|
@@ -296,13 +319,14 @@ bundle _1.17.3_ exec ruby benchmarks/request_overhead.rb
|
|
|
296
319
|
bundle _1.17.3_ exec ruby benchmarks/rails_notifications.rb
|
|
297
320
|
bundle _1.17.3_ exec ruby benchmarks/sidekiq_middleware.rb
|
|
298
321
|
bundle _1.17.3_ exec ruby benchmarks/apm_aggregation.rb
|
|
322
|
+
bundle _1.17.3_ exec ruby benchmarks/external_http.rb
|
|
299
323
|
```
|
|
300
324
|
|
|
301
325
|
Results depend on runtime, hardware, and payload. No performance comparison is claimed until repeatable measurements are published.
|
|
302
326
|
|
|
303
327
|
## Migration from Airbrake
|
|
304
328
|
|
|
305
|
-
An Airbrake migration guide will be added before the legacy 1.0 release. Version 0.
|
|
329
|
+
An Airbrake migration guide will be added before the legacy 1.0 release. Version 0.8 does not claim API compatibility or automatic replacement.
|
|
306
330
|
|
|
307
331
|
## Local development
|
|
308
332
|
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"type": "object",
|
|
16
16
|
"required": ["metric_type", "dimensions", "count", "error_count", "error_rate", "duration_ms", "histogram", "breakdown_ms", "signals", "status_codes"],
|
|
17
17
|
"properties": {
|
|
18
|
-
"metric_type": {"enum": ["request", "query", "job"]},
|
|
18
|
+
"metric_type": {"enum": ["request", "query", "job", "external_http"]},
|
|
19
19
|
"dimensions": {"type": "object"},
|
|
20
20
|
"count": {"type": "integer", "minimum": 1},
|
|
21
21
|
"error_count": {"type": "integer", "minimum": 0},
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://chronos.example/schemas/dependencies-v1.schema.json",
|
|
4
|
+
"title": "Chronos dependency inventory payload v1",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": false,
|
|
7
|
+
"required": ["dependencies", "ruby"],
|
|
8
|
+
"properties": {
|
|
9
|
+
"dependencies": {
|
|
10
|
+
"type": "array",
|
|
11
|
+
"maxItems": 200,
|
|
12
|
+
"items": {
|
|
13
|
+
"type": "object",
|
|
14
|
+
"additionalProperties": false,
|
|
15
|
+
"required": ["name", "version"],
|
|
16
|
+
"properties": {
|
|
17
|
+
"name": {"type": "string", "maxLength": 128},
|
|
18
|
+
"version": {"type": "string", "maxLength": 64}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"ruby": {
|
|
23
|
+
"type": "object",
|
|
24
|
+
"additionalProperties": false,
|
|
25
|
+
"required": ["version", "engine", "platform"],
|
|
26
|
+
"properties": {
|
|
27
|
+
"version": {"type": "string", "maxLength": 64},
|
|
28
|
+
"engine": {"type": "string", "maxLength": 64},
|
|
29
|
+
"platform": {"type": "string", "maxLength": 128}
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"rails": {"type": ["string", "null"], "maxLength": 128},
|
|
33
|
+
"web_server": {"type": ["string", "null"], "maxLength": 128},
|
|
34
|
+
"database_adapter": {"type": ["string", "null"], "maxLength": 128},
|
|
35
|
+
"sidekiq": {"type": ["string", "null"], "maxLength": 128},
|
|
36
|
+
"release": {"type": ["string", "null"], "maxLength": 128}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"properties": {
|
|
21
21
|
"schema_version": {"const": "1.0"},
|
|
22
22
|
"event_id": {"type": "string", "minLength": 1},
|
|
23
|
-
"event_type": {"enum": ["exception", "request", "query", "job", "cache", "metric_batch"]},
|
|
23
|
+
"event_type": {"enum": ["exception", "request", "query", "job", "cache", "external_http", "dependencies", "metric_batch"]},
|
|
24
24
|
"occurred_at": {"type": "string"},
|
|
25
25
|
"sent_at": {"type": "string"},
|
|
26
26
|
"project_key": {"type": "string", "minLength": 1},
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# ADR-016 — Explicit and privacy-bounded observability integrations
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Accepted for version 0.8.
|
|
6
|
+
|
|
7
|
+
## Context
|
|
8
|
+
|
|
9
|
+
Outbound calls, cache behavior, and runtime dependencies materially improve diagnosis, but global HTTP monkey patches and raw cache/dependency data create compatibility, cardinality, and privacy risks in legacy applications.
|
|
10
|
+
|
|
11
|
+
## Decision
|
|
12
|
+
|
|
13
|
+
Instrument only explicitly supplied `Net::HTTP` instances with a per-object prepended module. Preserve method, streaming block, response, and exception semantics. Collect only bounded host/outcome/timing fields and propagate only Chronos correlation headers.
|
|
14
|
+
|
|
15
|
+
Normalize Rails cache notifications through a core value normalizer. Omit raw keys by default and permit only an explicit project-scoped SHA-256 mode. Never inspect values.
|
|
16
|
+
|
|
17
|
+
Build one bounded dependency event per agent from already loaded gem specs and feature-detected constants. Do not inspect lockfiles or paths, activate dependencies, or open database connections. Route every event through the existing sanitizer, bounded queue, retry, circuit breaker, and backlog pipeline.
|
|
18
|
+
|
|
19
|
+
## Alternatives
|
|
20
|
+
|
|
21
|
+
A global `Net::HTTP` patch was rejected because it changes unrelated connections and increases conflict risk. Capturing full URLs, headers, bodies, cache keys, or lockfiles was rejected for privacy and cardinality. Attaching dependencies to every exception was rejected for redundant payload cost. Automatic Faraday and other client adapters were deferred until demand and official middleware boundaries are validated.
|
|
22
|
+
|
|
23
|
+
## Consequences
|
|
24
|
+
|
|
25
|
+
Applications choose exactly which HTTP clients are instrumented, native errors remain intact, and memory/data volume stay bounded. The tradeoffs are explicit setup per connection, partial dependency inventories when gems load late, pseudonymous rather than anonymous cache hashes, and no coverage for other HTTP clients in this release.
|
data/docs/architecture.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Architecture
|
|
2
2
|
|
|
3
|
-
Chronos Ruby 0.
|
|
3
|
+
Chronos Ruby 0.8 uses hexagonal boundaries so the legacy core remains independent of frameworks and delivery infrastructure.
|
|
4
4
|
|
|
5
5
|
```mermaid
|
|
6
6
|
flowchart TB
|
|
@@ -21,6 +21,9 @@ flowchart TB
|
|
|
21
21
|
Application --> Telemetry[Core / TelemetryEvent]
|
|
22
22
|
Telemetry --> APM[Application / ApmAggregator]
|
|
23
23
|
APM --> Metrics[Core / MetricAggregate and SqlNormalizer]
|
|
24
|
+
NetHTTP[Explicit Net::HTTP instance wrapper] --> Facade
|
|
25
|
+
Rails --> Cache[Core / CacheNormalizer]
|
|
26
|
+
Application --> Dependencies[Application / DependencyReporter]
|
|
24
27
|
```
|
|
25
28
|
|
|
26
29
|
## Boundaries
|
|
@@ -50,6 +53,8 @@ Sidekiq client middleware writes a versioned, allowlisted trace/request context
|
|
|
50
53
|
|
|
51
54
|
Version 0.7 routes request, query, and job observations through `ApmAggregator`. `SqlNormalizer` removes values before grouping, while `MetricAggregate` owns fixed numerical statistics. Aggregates and per-trace query trackers are bounded and mutex-protected. Threshold or lifecycle drains create `metric_batch` telemetry that passes through the existing sanitizer and delivery pipeline. No APM-specific thread is created.
|
|
52
55
|
|
|
56
|
+
Version 0.8 prepends a wrapper only to each explicitly selected `Net::HTTP` object. The wrapper records bounded outcome metadata and feeds the existing APM aggregator; it does not modify `Net::HTTP` globally. `CacheNormalizer` turns public Rails cache notifications into bounded metadata before delivery. `DependencyReporter` reads already loaded runtime metadata once per agent under a mutex and queues it as a separate event.
|
|
57
|
+
|
|
53
58
|
## Failure policy
|
|
54
59
|
|
|
55
60
|
Explicit invalid configuration raises `Chronos::ConfigurationError`. Capture, serialization, logger, worker, retry, circuit, TLS, network, HTTP, and remote-policy failures do not escape into the host application. They produce `false`, a classified transport result, a bounded state transition, or a bounded logger diagnostic.
|
data/docs/compatibility.md
CHANGED
|
@@ -21,6 +21,8 @@ Version `0.6.0.pre.1` uses the public Sidekiq 4/5 middleware signatures and rema
|
|
|
21
21
|
|
|
22
22
|
Version `0.7.0.pre.1` keeps the same Ruby/Rails matrix and implements APM aggregation without modern concurrency or SQL-parser dependencies. Its compatibility remains `Best effort` until request/SQL/job aggregate payloads pass the dedicated fake-server gates for every listed runtime.
|
|
23
23
|
|
|
24
|
+
Version `0.8.0.pre.1` uses per-object `Module#prepend`, legacy `Net::HTTP`, standard-library SHA-256, and loaded-spec feature detection. It adds no runtime dependency and keeps the same matrix. Outbound HTTP, cache, and dependency gates must pass every listed runtime before support is promoted.
|
|
25
|
+
|
|
24
26
|
Status meanings:
|
|
25
27
|
|
|
26
28
|
- Supported: the complete required compatibility gate passes.
|
data/docs/configuration.md
CHANGED
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
| `remote_configuration` | Optional | `true` | Accepts only the documented bounded remote policy fields |
|
|
40
40
|
| `remote_config_max_bytes` | Optional | `4096` | Maximum remote policy response-header bytes |
|
|
41
41
|
| `sampling_rate` | Optional | `1.0` | Local upper bound for event sampling |
|
|
42
|
-
| `enabled_event_types` | Optional | exception, request, query, job, cache, metric_batch | Local allowlist for supported event envelopes |
|
|
42
|
+
| `enabled_event_types` | Optional | exception, request, query, job, cache, external_http, dependencies, metric_batch | Local allowlist for supported event envelopes |
|
|
43
43
|
| `max_remote_send_interval` | Optional | `60.0` | Local upper bound for remotely requested send spacing |
|
|
44
44
|
| `context_store` | Optional | `:thread_local` | `:thread_local` or an object implementing `get`, `set`, `clear`, and `with_context` |
|
|
45
45
|
| `breadcrumb_capacity` | Optional | `20` | Positive count of newest breadcrumbs retained per execution |
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
| `rails_capture_in_console` | Optional | `false` | Enables automatic integration while Rails console is loaded |
|
|
49
49
|
| `rails_capture_in_test` | Optional | `false` | Enables automatic integration in the Rails test environment |
|
|
50
50
|
| `rails_capture_user_agent` | Optional | `false` | Adds the Rack user agent to request context |
|
|
51
|
-
| `apm_enabled` | Optional | `true` | Aggregates request, query, and
|
|
51
|
+
| `apm_enabled` | Optional | `true` | Aggregates request, query, job, and enabled external HTTP observations into bounded metric batches |
|
|
52
52
|
| `apm_max_groups` | Optional | `200` | Maximum metric groups and active trace trackers retained locally |
|
|
53
53
|
| `apm_flush_count` | Optional | `100` | Aggregate observations accepted before a threshold drain |
|
|
54
54
|
| `apm_batch_size` | Optional | `50` | Metric groups per batch; hard maximum 50 |
|
|
@@ -57,6 +57,11 @@
|
|
|
57
57
|
| `apm_long_transaction_threshold_ms` | Optional | `1000.0` | Transaction-labelled SQL duration that produces a signal |
|
|
58
58
|
| `apm_n_plus_one_threshold` | Optional | `5` | Repeated fingerprint count producing one possible-N+1 signal; minimum 2 |
|
|
59
59
|
| `apm_histogram_buckets` | Optional | Fixed millisecond boundaries | Increasing positive duration boundaries; at most 19 plus `+Inf` |
|
|
60
|
+
| `external_http_enabled` | Optional | `false` | Allows explicit per-instance outbound `Net::HTTP` instrumentation |
|
|
61
|
+
| `external_http_trace_headers` | Optional | `true` | Propagates Chronos trace/request headers on instrumented requests |
|
|
62
|
+
| `cache_key_mode` | Optional | `:none` | `:none` omits keys; `:sha256` emits a project-scoped key hash |
|
|
63
|
+
| `dependency_reporting` | Optional | `true` | Emits one bounded dependency event per configured agent |
|
|
64
|
+
| `dependency_max_items` | Optional | `100` | Loaded gem entries retained in the inventory; range 1–200 |
|
|
60
65
|
|
|
61
66
|
```ruby
|
|
62
67
|
Chronos.configure do |config|
|
|
@@ -84,6 +89,11 @@ Chronos.configure do |config|
|
|
|
84
89
|
config.apm_slow_query_threshold_ms = 500.0
|
|
85
90
|
config.apm_long_transaction_threshold_ms = 1000.0
|
|
86
91
|
config.apm_n_plus_one_threshold = 5
|
|
92
|
+
config.external_http_enabled = false
|
|
93
|
+
config.external_http_trace_headers = true
|
|
94
|
+
config.cache_key_mode = :none
|
|
95
|
+
config.dependency_reporting = true
|
|
96
|
+
config.dependency_max_items = 100
|
|
87
97
|
end
|
|
88
98
|
```
|
|
89
99
|
|
data/docs/data-collected.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Data collected
|
|
2
2
|
|
|
3
|
-
Version 0.
|
|
3
|
+
Version 0.8 emits exceptions, cache telemetry, one dependency inventory, and aggregated request/query/job/external-HTTP metric batches. All fields pass through the privacy sanitizer and bounded safe serializer before queueing, retry storage, or delivery.
|
|
4
4
|
|
|
5
5
|
| Data | Default | Source |
|
|
6
6
|
|---|---|---|
|
|
@@ -34,14 +34,19 @@ Version 0.7 emits exceptions, individual cache telemetry, and aggregated request
|
|
|
34
34
|
| Sidekiq trace/request IDs | Propagated when present; trace generated otherwise | Chronos job-envelope metadata |
|
|
35
35
|
| APM counts, error counts/rates, duration total/min/max/average | Aggregated by default | Request, query, and job observations |
|
|
36
36
|
| Fixed duration histogram and status counts | Aggregated by default | Local bounded counters |
|
|
37
|
-
| Component breakdown | database/view/cache/queue/application when observable | Trace-local bounded totals |
|
|
37
|
+
| Component breakdown | database/view/external_http/cache/queue/application when observable | Trace-local bounded totals |
|
|
38
38
|
| Normalized SQL and SHA-256 fingerprint | Collected without comments, literals, or binds | `sql.active_record` payload |
|
|
39
39
|
| SQL adapter, operation, inferred table, AR name, cache flag, role/shard | Collected when exposed | Public notification payload and connection feature detection |
|
|
40
40
|
| Slow SQL source frame | Collected only for threshold-selected slow queries | Bounded application call frame |
|
|
41
41
|
| APM diagnostic signals | Heuristic counters | Local threshold and repetition detection |
|
|
42
|
-
|
|
|
42
|
+
| External HTTP host, method, status, duration, timeout, connection-error flag, error class | Disabled by default; per-instance opt-in | Instrumented `Net::HTTP` object |
|
|
43
|
+
| Chronos trace/request headers | Propagated when available | Current execution context |
|
|
44
|
+
| Cache operation, backend, namespace, hit/miss, duration | Collected; key/value omitted | ActiveSupport cache notifications |
|
|
45
|
+
| Cache key hash | Disabled by default | Project-scoped SHA-256 when `cache_key_mode = :sha256` |
|
|
46
|
+
| Loaded gem names/versions and Ruby runtime | Once per agent by default; bounded | `Gem.loaded_specs` and Ruby constants |
|
|
47
|
+
| Rails, web server, database adapter, Sidekiq, release | Included when safely detectable/configured | Loaded constants/specs and `app_version` |
|
|
43
48
|
|
|
44
|
-
The gem never collects request bodies, response bodies, raw query strings, cookies, HTTP authorization headers, environment variables in bulk, source code, raw SQL, SQL bind values, database rows, cache keys/values, mail bodies/recipients, or
|
|
49
|
+
The gem never collects request bodies, response bodies, raw query strings, cookies, HTTP authorization headers, environment variables in bulk, source code, raw SQL, SQL bind values, database rows, raw cache keys/values, mail bodies/recipients, gem paths, or lockfile contents. Sidekiq JIDs/arguments and bounded loaded gem names/versions are documented integration fields.
|
|
45
50
|
|
|
46
51
|
APM dimensions never include user ID, job ID, raw URL, exception message, bind value, or cache key. Normalized routes replace common numeric/UUID segments. Normalized SQL can retain schema, table, and column identifiers; review those identifiers as part of the privacy audit.
|
|
47
52
|
|
data/docs/examples/plain-ruby.md
CHANGED
|
@@ -23,4 +23,10 @@ For a network-free outage and bounded-backlog example, run:
|
|
|
23
23
|
bundle _1.17.3_ exec ruby examples/plain-ruby/resilient_delivery.rb
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
For network-free per-instance outbound HTTP instrumentation, run:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
bundle _1.17.3_ exec ruby examples/plain-ruby/external_http.rb
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
The examples demonstrate final event construction, key redaction, e-mail and Bearer-token detection, application-specific blocklisting, identifier hashing, and the bounded external HTTP payload without opening a socket.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Essential APM aggregation
|
|
2
2
|
|
|
3
|
-
Version `0.
|
|
3
|
+
Version `0.8.0.pre.1` aggregates request, SQL, job, and explicitly instrumented external HTTP observations locally before delivery. The agent emits versioned `metric_batch` envelopes containing at most 50 metric groups instead of one event per observation. Aggregates drain when `apm_flush_count` observations are reached and whenever `Chronos.flush` or `Chronos.close` runs. No timer or additional APM thread is created.
|
|
4
4
|
|
|
5
5
|
## Request metrics
|
|
6
6
|
|
|
@@ -35,7 +35,7 @@ New groups beyond capacity are dropped and counted in `dropped_groups`. Existing
|
|
|
35
35
|
|
|
36
36
|
## Breakdown
|
|
37
37
|
|
|
38
|
-
The contract supports `database`, `view`, `external_http`, `cache`, `queue`, `application`, and `unknown`. Version 0.
|
|
38
|
+
The contract supports `database`, `view`, `external_http`, `cache`, `queue`, `application`, and `unknown`. Version 0.8 fills external HTTP time for explicitly instrumented calls inside a traced request, in addition to database/view/cache, queue/application for jobs, and residual application request time.
|
|
39
39
|
|
|
40
40
|
## Configuration
|
|
41
41
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Cache observability
|
|
2
|
+
|
|
3
|
+
Rails ActiveSupport cache notifications produce individual bounded `cache` events containing operation, duration, hit/miss outcome, backend, and namespace. When a trace is active, duration also contributes to the request's cache breakdown.
|
|
4
|
+
|
|
5
|
+
Raw cache keys and values are never delivered. The default `cache_key_mode = :none` omits key identity entirely. Applications that need correlation can opt into a project-scoped SHA-256 value:
|
|
6
|
+
|
|
7
|
+
```ruby
|
|
8
|
+
Chronos.configure do |config|
|
|
9
|
+
# connection settings omitted
|
|
10
|
+
config.cache_key_mode = :sha256
|
|
11
|
+
end
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Hashing accepts at most 2,048 bytes of key text and emits a fixed 64-character hexadecimal value. It is pseudonymization rather than anonymization: an attacker who can guess a low-entropy key may reproduce candidate hashes when project scope is known. Do not encode credentials or unnecessary personal data in cache keys.
|
|
15
|
+
|
|
16
|
+
The normalizer never calls cache read/write APIs, inspects cached values, or retains keys. Unsupported or incomplete notification payloads become an `unknown` outcome without raising into Rails.
|
|
@@ -9,3 +9,5 @@ Risks include accidentally logging credentials and changing settings while event
|
|
|
9
9
|
Tests in `spec/unit/configuration_spec.rb` verify required fields, HTTPS defaults, immutable containers, disabled operation, and bounded numeric settings.
|
|
10
10
|
|
|
11
11
|
Version 0.7 adds bounded APM capacities, thresholds, and histogram boundaries. Invalid zero/negative capacities, batches above 50, N+1 thresholds below two, and non-increasing histogram boundaries are rejected before agent construction. See [Essential APM aggregation](apm-aggregation.md).
|
|
12
|
+
|
|
13
|
+
Version 0.8 adds Boolean HTTP/dependency switches, `:none`/`:sha256` cache-key policy, and a dependency limit from 1 to 200. Invalid values are rejected before instrumentation or collection starts. See [External HTTP](external-http.md), [Cache observability](cache-observability.md), and [Dependency inventory](dependencies.md).
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Dependency inventory
|
|
2
|
+
|
|
3
|
+
Version `0.8.0.pre.1` emits a separate `dependencies` event at most once per configured agent. It is queued before the first capture or during explicit flush/close and is never attached to each exception.
|
|
4
|
+
|
|
5
|
+
The inventory contains Ruby version/engine/platform, bounded names and versions from already loaded gem specs, the configured `app_version` release identifier, and Rails, Sidekiq, web server, or database adapter labels when safely detectable. The agent does not parse `Gemfile.lock`, activate missing gems, inspect gem paths/source, scan environment variables, open a database connection, or collect dependency configuration.
|
|
6
|
+
|
|
7
|
+
```ruby
|
|
8
|
+
Chronos.configure do |config|
|
|
9
|
+
# connection settings omitted
|
|
10
|
+
config.dependency_reporting = true
|
|
11
|
+
config.dependency_max_items = 100
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Optional after application boot, before the first regular event:
|
|
15
|
+
Chronos.report_dependencies
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
`dependency_max_items` accepts 1–200 and defaults to 100. Entries are sorted by name before truncation so repeated boots are stable. Set `dependency_reporting = false` when inventory collection is unnecessary or prohibited. Because collection is once-only, gems loaded after the first event appear only after a new agent configuration or process boot.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# External HTTP instrumentation
|
|
2
|
+
|
|
3
|
+
Version `0.8.0.pre.1` provides an optional `Net::HTTP` wrapper loaded through `chronos/net_http`. It is disabled by default and prepended only to a connection object explicitly passed to `Chronos.instrument_net_http`; the `Net::HTTP` class and unrelated instances are unchanged.
|
|
4
|
+
|
|
5
|
+
```ruby
|
|
6
|
+
require "net/http"
|
|
7
|
+
require "chronos"
|
|
8
|
+
|
|
9
|
+
Chronos.configure do |config|
|
|
10
|
+
# connection settings omitted
|
|
11
|
+
config.external_http_enabled = true
|
|
12
|
+
config.external_http_trace_headers = true
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
http = Net::HTTP.new("payments.example.com", 443)
|
|
16
|
+
http.use_ssl = true
|
|
17
|
+
Chronos.instrument_net_http(http)
|
|
18
|
+
response = http.request(Net::HTTP::Get.new("/health"))
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
The event contains a bounded lowercase host, uppercase method, response status, monotonic duration, timeout flag, connection-error flag, and error class. A request made inside a Chronos context receives `X-Chronos-Trace-ID` and `X-Chronos-Request-ID` unless the application already set those headers. Disable propagation with `external_http_trace_headers = false`.
|
|
22
|
+
|
|
23
|
+
The wrapper never reads or records the path, query string, Authorization, other request headers, request body, response headers/body, or exception message. The native streaming block is forwarded and the identical HTTP exception is re-raised. Telemetry failures are contained.
|
|
24
|
+
|
|
25
|
+
Successful and failed calls become bounded `external_http` APM groups keyed only by host and method. A call carrying a trace ID contributes its duration to the enclosing request's `external_http` breakdown. Faraday, HTTP.rb, Excon, and RestClient are outside this release.
|
|
26
|
+
|
|
27
|
+
Installation is idempotent per object. A `false` result means collection is disabled, the object is incompatible or already instrumented, or installation was contained after an internal error.
|
|
@@ -29,7 +29,7 @@ The public `ActiveSupport::Notifications.subscribe` API is used for:
|
|
|
29
29
|
| `sql.active_record` | `query` | operation name, cached flag, and duration |
|
|
30
30
|
| `deliver.action_mailer` | `job` with `kind=mailer` | mailer, action, and duration |
|
|
31
31
|
| `perform.active_job` | `job` | job class, queue, and duration, when Active Job is available |
|
|
32
|
-
| cache read/write/hit notifications | `cache` | operation,
|
|
32
|
+
| cache read/write/hit notifications | `cache` | operation, backend, namespace, hit/miss, duration, and optional scoped key hash |
|
|
33
33
|
|
|
34
34
|
Raw SQL, binds, cache keys, mail recipients and bodies, job IDs and arguments, request/response bodies, cookies, and authorization headers are not copied. Template identifiers are reduced to their basename. Every event passes through `Sanitizer`, `SafeSerializer`, the bounded queue, retry policy, circuit breaker, and memory backlog.
|
|
35
35
|
|
|
@@ -4,7 +4,7 @@ Version `0.6.0.pre.1` starts the legacy jobs line with optional Sidekiq 4 and 5
|
|
|
4
4
|
|
|
5
5
|
```ruby
|
|
6
6
|
gem "sidekiq", "~> 5.0"
|
|
7
|
-
gem "chronos-ruby", "0.
|
|
7
|
+
gem "chronos-ruby", "0.8.0.pre.1", :require => "chronos/sidekiq"
|
|
8
8
|
```
|
|
9
9
|
|
|
10
10
|
`chronos/sidekiq` installs middleware through the public `configure_client` and `configure_server` APIs. It does nothing when Sidekiq is unavailable, and the core gem never requires Sidekiq. Installation adds no Chronos thread or Redis/database connection per job; delivery continues through the agent's existing fixed worker pool.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# Framework telemetry events
|
|
2
2
|
|
|
3
|
-
`Chronos::Core::TelemetryEvent` and `Chronos::Core::TelemetrySerializer` extend the v1 envelope to `request`, `query`, `job`, and `
|
|
3
|
+
`Chronos::Core::TelemetryEvent` and `Chronos::Core::TelemetrySerializer` extend the v1 envelope to `request`, `query`, `job`, `cache`, `external_http`, `dependencies`, and `metric_batch` events. These values exist so integrations do not model operational telemetry as fake exceptions.
|
|
4
4
|
|
|
5
5
|
Telemetry has the same `schema_version`, event ID, timestamps, project, environment, service, runtime, context, sanitization, payload-size limit, idempotency header, asynchronous queue, retry, circuit breaker, and memory backlog used by exception events. Unsupported types are rejected locally.
|
|
6
6
|
|
|
7
7
|
`Chronos.record_event` is the narrow integration entry point. Application code should prefer documented higher-level APIs; its payload is allowlisted by each bundled integration and then sanitized. Remote configuration can reduce or disable any locally enabled telemetry type but cannot enable a type excluded by local configuration.
|
|
8
8
|
|
|
9
|
-
Version 0.
|
|
9
|
+
Version 0.8 aggregates request, query, job, and enabled external HTTP observations into `metric_batch` events by default. Cache remains an individual event while contributing to an existing traced request breakdown. Dependencies use one separate event per agent. Set `apm_enabled = false` only when individual legacy telemetry is required for diagnostics. Percentiles remain server-side; see [Essential APM aggregation](apm-aggregation.md).
|
data/docs/performance.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Performance
|
|
2
2
|
|
|
3
|
-
Performance is a functional requirement, but version 0.
|
|
3
|
+
Performance is a functional requirement, but version 0.8 makes no unverified speed claim.
|
|
4
4
|
|
|
5
5
|
Current controls:
|
|
6
6
|
|
|
@@ -21,6 +21,9 @@ Current controls:
|
|
|
21
21
|
- Rails subscribers copy only small allowlisted field sets and never copy raw SQL or job arguments.
|
|
22
22
|
- Sidekiq middleware creates no per-job thread or connection and bounds arguments, collections, nesting, strings, and tags before telemetry capture.
|
|
23
23
|
- APM group, trace, query-fingerprint, histogram, and batch counts are fixed; no APM timer thread is created.
|
|
24
|
+
- outbound HTTP instrumentation uses two clock reads and bounded metadata without body/header traversal;
|
|
25
|
+
- cache normalization is bounded and SHA-256 runs only when explicitly enabled;
|
|
26
|
+
- dependency inventory runs at most once per agent and is capped at 200 loaded specs.
|
|
24
27
|
|
|
25
28
|
Run the scripts under `benchmarks/` and record Ruby version, operating system, CPU, warmup, iteration count, median, and dispersion before publishing results. `benchmarks/filtering.rb` measures privacy filtering, `benchmarks/retry_backlog.rb` measures fixed-memory outage behavior, `benchmarks/request_overhead.rb` compares Rack-protocol calls, and `benchmarks/rails_notifications.rb` isolates subscriber normalization overhead.
|
|
26
29
|
|
|
@@ -100,3 +103,15 @@ ITERATIONS=100000 bundle _1.17.3_ exec ruby benchmarks/apm_aggregation.rb
|
|
|
100
103
|
The fixture repeatedly updates one SQL metric group and one trace-local fingerprint. It excludes ActiveSupport dispatch, serialization, queueing, and network delivery. The benchmark must report one retained group; memory must remain bounded by configuration. Record runtime, hardware, warmup, median, and dispersion before publishing a performance claim.
|
|
101
104
|
|
|
102
105
|
A local diagnostic run on 2026-07-20 used Ruby 2.2.10 on macOS arm64 and 10,000 observations. It retained one group and measured approximately 34.972 microseconds per observation. This single run has no controlled warmup, median, or dispersion and is not a production performance claim.
|
|
106
|
+
|
|
107
|
+
## Version 0.8 external HTTP benchmark
|
|
108
|
+
|
|
109
|
+
Run:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
ITERATIONS=100000 bundle _1.17.3_ exec ruby benchmarks/external_http.rb
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
The fixture compares a no-op Net::HTTP-compatible object with the per-instance wrapper. It includes trace-header injection, bounded outcome capture, and clock reads, but excludes DNS, sockets, TLS, serialization, queueing, and network delivery. Record a controlled result before making a performance claim.
|
|
116
|
+
|
|
117
|
+
A local diagnostic run on 2026-07-20 used Ruby 2.2.10 on macOS arm64 and 10,000 calls. It measured approximately 15.155 microseconds of wrapper overhead per call. This single run has no controlled warmup, median, or dispersion and is not a production performance claim.
|
data/docs/privacy-lgpd.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Privacy and LGPD
|
|
2
2
|
|
|
3
|
-
Version 0.
|
|
3
|
+
Version 0.8 sanitizes exception, framework telemetry, dependency inventory, and APM metric batches before JSON serialization, queueing, retry backlog, or transport. This reduces accidental exposure, but the host application remains responsible for lawful purpose, minimization, access control, retention, and responses to data-subject requests.
|
|
4
4
|
|
|
5
5
|
## Default policy
|
|
6
6
|
|
|
@@ -16,8 +16,17 @@ Version 0.7 sanitizes exception, framework telemetry, and APM metric batches bef
|
|
|
16
16
|
| Request/response bodies, raw query strings, cookies, authorization headers, raw SQL/binds, cache values, mail bodies, environment variables | Never collected automatically |
|
|
17
17
|
| Sidekiq arguments | Collected automatically, limited before sanitization, then redacted by the common policy |
|
|
18
18
|
| SQL | Comments, quoted/numeric/boolean/null literals removed; binds never read; bounded identifiers remain |
|
|
19
|
+
| External HTTP | Host/method/status/timing only; URL path/query, Authorization, bodies, headers, and error messages omitted |
|
|
20
|
+
| Cache key | Omitted by default; optional project-scoped SHA-256 hash; cache value never read |
|
|
21
|
+
| Dependencies | Bounded loaded gem names/versions and detected runtime labels; paths and lockfiles omitted |
|
|
19
22
|
|
|
20
|
-
The retry backlog exists only in process memory, accepts only `SerializedEvent`, has a fixed capacity, and disappears on process exit. Version 0.
|
|
23
|
+
The retry backlog exists only in process memory, accepts only `SerializedEvent`, has a fixed capacity, and disappears on process exit. Version 0.8 does not persist telemetry to disk.
|
|
24
|
+
|
|
25
|
+
## External services, cache, and dependencies
|
|
26
|
+
|
|
27
|
+
Outbound HTTP instrumentation is disabled by default and installed per connection. Trace headers reveal correlation identifiers to the selected destination; enable propagation only for destinations permitted to receive them. The wrapper does not inspect any other header or URL component.
|
|
28
|
+
|
|
29
|
+
Raw cache keys can contain user or business data and are never delivered. Optional hashing is pseudonymization, not anonymization: predictable low-entropy keys can still be guessed. Dependency reporting is a separate once-per-agent event, never copied into exceptions, and can be disabled. It reads loaded gem name/version pairs only, with no filesystem path, source, configuration, or complete lockfile.
|
|
21
30
|
|
|
22
31
|
## Rails telemetry
|
|
23
32
|
|
data/docs/troubleshooting.md
CHANGED
|
@@ -22,7 +22,19 @@ Require `chronos/rails` from the generated initializer and confirm it runs befor
|
|
|
22
22
|
|
|
23
23
|
## Rails telemetry contains no SQL or cache key
|
|
24
24
|
|
|
25
|
-
This is intentional.
|
|
25
|
+
This is intentional. Chronos records bounded SQL and cache operational metadata without raw statements, binds, keys, or values. Set `cache_key_mode = :sha256` before configuration only when a stable pseudonymous key identity is required.
|
|
26
|
+
|
|
27
|
+
## External HTTP telemetry is missing
|
|
28
|
+
|
|
29
|
+
Set `external_http_enabled = true`, then call `Chronos.instrument_net_http(http)` for each `Net::HTTP` instance after Chronos is configured. Existing and future objects are not patched globally. The method returns `false` when disabled, already installed, incompatible, or unconfigured.
|
|
30
|
+
|
|
31
|
+
## Trace headers should not reach a destination
|
|
32
|
+
|
|
33
|
+
Set `external_http_trace_headers = false` before configuring the agent, or do not instrument that connection. Chronos preserves an application-supplied Chronos header instead of overwriting it.
|
|
34
|
+
|
|
35
|
+
## Dependency inventory is missing or incomplete
|
|
36
|
+
|
|
37
|
+
The event is emitted once per agent and contains only gems loaded at collection time, capped by `dependency_max_items`. It does not parse the lockfile or activate optional frameworks. Call `Chronos.report_dependencies` after application boot if the first event can occur before all integrations load, or set `dependency_reporting = false` to disable collection.
|
|
26
38
|
|
|
27
39
|
## Sidekiq telemetry is missing
|
|
28
40
|
|