chronos-ruby 0.5.0.pre.1 → 0.7.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 +46 -0
- data/README.md +37 -8
- data/contracts/apm-batch-v1.schema.json +35 -0
- data/contracts/event-v1.schema.json +1 -1
- data/contracts/sidekiq-job-v1.schema.json +21 -0
- data/docs/adr/ADR-014-sidekiq-envelope-context.md +27 -0
- data/docs/adr/ADR-015-bounded-apm-aggregation.md +27 -0
- data/docs/architecture.md +10 -1
- data/docs/compatibility.md +8 -0
- data/docs/configuration.md +18 -1
- data/docs/data-collected.md +16 -2
- data/docs/modules/apm-aggregation.md +57 -0
- data/docs/modules/configuration.md +2 -0
- data/docs/modules/rails-legacy.md +1 -1
- data/docs/modules/sidekiq-legacy.md +23 -0
- data/docs/modules/telemetry-events.md +1 -1
- data/docs/performance.md +25 -1
- data/docs/privacy-lgpd.md +13 -3
- data/docs/troubleshooting.md +20 -0
- data/lib/chronos/agent.rb +40 -0
- data/lib/chronos/application/apm_aggregator.rb +273 -0
- data/lib/chronos/application/capture_telemetry.rb +45 -5
- data/lib/chronos/application/delivery_pipeline.rb +7 -0
- data/lib/chronos/application/remote_configuration.rb +6 -1
- data/lib/chronos/configuration/apm_validation.rb +60 -0
- data/lib/chronos/configuration.rb +22 -2
- data/lib/chronos/core/metric_aggregate.rb +113 -0
- data/lib/chronos/core/sql_normalizer.rb +114 -0
- data/lib/chronos/core/telemetry_event.rb +1 -1
- data/lib/chronos/integrations/job_payload.rb +72 -0
- data/lib/chronos/integrations/rack/middleware.rb +19 -1
- data/lib/chronos/integrations/sidekiq.rb +260 -0
- data/lib/chronos/internal/worker_pool.rb +19 -2
- data/lib/chronos/rails/notifications_subscriber.rb +36 -4
- data/lib/chronos/sidekiq.rb +12 -0
- data/lib/chronos/version.rb +1 -1
- data/lib/chronos.rb +25 -0
- metadata +15 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b9cf448c12955078e3a714df2d41bcd94d89f840fea406dc6595f72661e8abc2
|
|
4
|
+
data.tar.gz: 1401d283792e930caa252b21191de3d8fcc02bf5b2936416ed28eec2e319dab3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 43f80510ce3d78e6c9b4b571f7d79cb66b8a4fad8f36b66996ea5cc42868c6ec7b1a05ae1556c8442569787f2f350e2884a779e36af649734eced377396c892b
|
|
7
|
+
data.tar.gz: 30b0f93cfba0ce2fb856b4c65eff6e1ebfa906c8c45ec5c6e287ddc080bc23bd63e4e1a7a4d80a56f40b5001c768719c3b52a2d7e9b08d08b39a2512b476db30
|
data/CHANGELOG.md
CHANGED
|
@@ -6,11 +6,57 @@ All notable changes are documented here. The project follows Semantic Versioning
|
|
|
6
6
|
|
|
7
7
|
### Fixed
|
|
8
8
|
|
|
9
|
+
- `WorkerPool#flush` no longer returns before a worker marks a just-popped event as active;
|
|
9
10
|
- release publishing now updates RubyGems to a Ruby 2.6-compatible version that supports `GEM_HOST_API_KEY`.
|
|
10
11
|
- Updated the legacy development toolchain to non-vulnerable Rake and RuboCop versions.
|
|
11
12
|
- legacy CI now resolves Bundler 1.17.3 through `Gem.bin_path` on RubyGems versions that do not support the `_version_` executable selector.
|
|
12
13
|
- documentation verification now reads source and Markdown files explicitly as UTF-8 on legacy container locales.
|
|
13
14
|
|
|
15
|
+
## [0.7.0.pre.1] - 2026-07-20
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- bounded local request, SQL, and job aggregation with count, error rate, duration statistics, histograms, status codes, and component breakdown;
|
|
20
|
+
- `metric_batch` v1 payloads containing at most 50 sanitized metric groups;
|
|
21
|
+
- bounded SQL normalization, fingerprinting, adapter/operation/table/name/cache/role/shard dimensions, and sampled slow-query source;
|
|
22
|
+
- heuristic slow-query, repeated-query, possible N+1, long-transaction, connection-error, and deadlock signals;
|
|
23
|
+
- generic Rack request metrics with Rails/Rack deduplication;
|
|
24
|
+
- APM configuration, diagnostics, contracts, tests, example, benchmark, module documentation, and ADR-015.
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
|
|
28
|
+
- request, query, and job observations aggregate by default instead of producing one delivery event each;
|
|
29
|
+
- `Chronos.flush` and `Chronos.close` drain APM aggregates before delivery shutdown;
|
|
30
|
+
- version advanced to `0.7.0.pre.1`.
|
|
31
|
+
|
|
32
|
+
### Known limitations
|
|
33
|
+
|
|
34
|
+
- local signals are heuristic and require server-side confirmation;
|
|
35
|
+
- incomplete trace trackers are cleared when aggregates drain;
|
|
36
|
+
- normalized SQL is defensive rather than a complete dialect parser;
|
|
37
|
+
- external HTTP breakdown remains version 0.8 scope.
|
|
38
|
+
|
|
39
|
+
## [0.6.0.pre.1] - 2026-07-20
|
|
40
|
+
|
|
41
|
+
### Added
|
|
42
|
+
|
|
43
|
+
- optional Sidekiq 4/5 client and server middleware loaded through `chronos/sidekiq`;
|
|
44
|
+
- versioned trace/request context propagation beside, never inside, public job arguments;
|
|
45
|
+
- Sidekiq class, queue, JID, retry count, duration, calculable latency, bounded arguments, tags, status, and error telemetry;
|
|
46
|
+
- shared per-job exception deduplication for nested Sidekiq and Active Job capture paths;
|
|
47
|
+
- Sidekiq payload contract, unit/integration tests, executable example, benchmark, module documentation, and ADR-014.
|
|
48
|
+
|
|
49
|
+
### Changed
|
|
50
|
+
|
|
51
|
+
- version advanced to `0.6.0.pre.1`;
|
|
52
|
+
- the public facade exposes bounded propagation context for optional process-boundary integrations.
|
|
53
|
+
|
|
54
|
+
### Known limitations
|
|
55
|
+
|
|
56
|
+
- Sidekiq 4/5 remains `Best effort` until dedicated real-gem matrix jobs pass;
|
|
57
|
+
- Active Job context propagation, Resque, and Delayed Job remain subsequent version 0.6 increments;
|
|
58
|
+
- Sidekiq argument capture is automatic, though strictly bounded and sanitized.
|
|
59
|
+
|
|
14
60
|
## [0.4.0.pre.1] - 2026-07-20
|
|
15
61
|
|
|
16
62
|
### 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.7 adds bounded essential APM aggregation for requests, SQL, and jobs, including histograms, error rates, component breakdown, normalized SQL fingerprints, and local diagnostic signals.
|
|
4
4
|
|
|
5
5
|
## What the gem collects
|
|
6
6
|
|
|
7
|
-
For each exception, version 0.
|
|
7
|
+
For each exception, version 0.7 can collect:
|
|
8
8
|
|
|
9
9
|
- exception class, message, structured backtrace, and chained causes;
|
|
10
10
|
- timestamp, severity, tags, and an optional fingerprint;
|
|
@@ -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.7.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.7.0.pre.1", :require => "chronos/rails"
|
|
56
56
|
```
|
|
57
57
|
|
|
58
58
|
Generate the initializer with:
|
|
@@ -168,11 +168,35 @@ Local exception-specific ignore callbacks are not available in version 0.4. The
|
|
|
168
168
|
|
|
169
169
|
## Performance monitoring
|
|
170
170
|
|
|
171
|
-
Version 0.
|
|
171
|
+
Version 0.7 aggregates request, query, and job observations into bounded `metric_batch` events. Groups include count, error count/rate, total/min/max/average duration, fixed histogram buckets, status counts, and component breakdown. Percentiles are calculated in the SaaS without retaining every local duration.
|
|
172
|
+
|
|
173
|
+
SQL comments and literal values are removed before a bounded normalized query and SHA-256 fingerprint are produced. Binds are never read. Slow, repeated, possible N+1, long-transaction, connection-error, and deadlock signals are heuristic and require server-side confirmation. Group count, active trace count, fingerprints per trace, histogram buckets, and batch size all have fixed limits. See [Essential APM aggregation](docs/modules/apm-aggregation.md).
|
|
174
|
+
|
|
175
|
+
```ruby
|
|
176
|
+
Chronos.configure do |config|
|
|
177
|
+
# required connection settings omitted
|
|
178
|
+
config.apm_enabled = true
|
|
179
|
+
config.apm_max_groups = 200
|
|
180
|
+
config.apm_flush_count = 100
|
|
181
|
+
config.apm_batch_size = 50
|
|
182
|
+
config.apm_max_queries_per_request = 100
|
|
183
|
+
config.apm_slow_query_threshold_ms = 500.0
|
|
184
|
+
config.apm_n_plus_one_threshold = 5
|
|
185
|
+
end
|
|
186
|
+
```
|
|
172
187
|
|
|
173
188
|
## Sidekiq and Active Job
|
|
174
189
|
|
|
175
|
-
Version 0.
|
|
190
|
+
Version `0.6.0.pre.1` adds optional Sidekiq 4/5 middleware:
|
|
191
|
+
|
|
192
|
+
```ruby
|
|
193
|
+
gem "sidekiq", "~> 5.0"
|
|
194
|
+
gem "chronos-ruby", "0.7.0.pre.1", :require => "chronos/sidekiq"
|
|
195
|
+
```
|
|
196
|
+
|
|
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
|
+
|
|
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.
|
|
176
200
|
|
|
177
201
|
## Deploy tracking
|
|
178
202
|
|
|
@@ -246,6 +270,9 @@ Chronos.configure do |config|
|
|
|
246
270
|
config.context_store = :thread_local
|
|
247
271
|
config.breadcrumb_capacity = 20
|
|
248
272
|
config.breadcrumb_max_bytes = 2048
|
|
273
|
+
config.apm_enabled = true
|
|
274
|
+
config.apm_max_groups = 200
|
|
275
|
+
config.apm_flush_count = 100
|
|
249
276
|
end
|
|
250
277
|
```
|
|
251
278
|
|
|
@@ -257,7 +284,7 @@ Configuration errors are raised during `Chronos.configure`. Capture and delivery
|
|
|
257
284
|
|
|
258
285
|
## Benchmark
|
|
259
286
|
|
|
260
|
-
Run the version 0.
|
|
287
|
+
Run the version 0.7 benchmarks with:
|
|
261
288
|
|
|
262
289
|
```bash
|
|
263
290
|
bundle _1.17.3_ exec ruby benchmarks/capture_exception.rb
|
|
@@ -267,13 +294,15 @@ bundle _1.17.3_ exec ruby benchmarks/queue.rb
|
|
|
267
294
|
bundle _1.17.3_ exec ruby benchmarks/retry_backlog.rb
|
|
268
295
|
bundle _1.17.3_ exec ruby benchmarks/request_overhead.rb
|
|
269
296
|
bundle _1.17.3_ exec ruby benchmarks/rails_notifications.rb
|
|
297
|
+
bundle _1.17.3_ exec ruby benchmarks/sidekiq_middleware.rb
|
|
298
|
+
bundle _1.17.3_ exec ruby benchmarks/apm_aggregation.rb
|
|
270
299
|
```
|
|
271
300
|
|
|
272
301
|
Results depend on runtime, hardware, and payload. No performance comparison is claimed until repeatable measurements are published.
|
|
273
302
|
|
|
274
303
|
## Migration from Airbrake
|
|
275
304
|
|
|
276
|
-
An Airbrake migration guide will be added before the legacy 1.0 release. Version 0.
|
|
305
|
+
An Airbrake migration guide will be added before the legacy 1.0 release. Version 0.7 does not claim API compatibility or automatic replacement.
|
|
277
306
|
|
|
278
307
|
## Local development
|
|
279
308
|
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://chronos.example/schemas/apm-batch-v1.schema.json",
|
|
4
|
+
"title": "Chronos APM metric batch payload v1",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": false,
|
|
7
|
+
"required": ["metrics", "dropped_groups"],
|
|
8
|
+
"properties": {
|
|
9
|
+
"dropped_groups": {"type": "integer", "minimum": 0},
|
|
10
|
+
"metrics": {
|
|
11
|
+
"type": "array",
|
|
12
|
+
"minItems": 1,
|
|
13
|
+
"maxItems": 50,
|
|
14
|
+
"items": {
|
|
15
|
+
"type": "object",
|
|
16
|
+
"required": ["metric_type", "dimensions", "count", "error_count", "error_rate", "duration_ms", "histogram", "breakdown_ms", "signals", "status_codes"],
|
|
17
|
+
"properties": {
|
|
18
|
+
"metric_type": {"enum": ["request", "query", "job"]},
|
|
19
|
+
"dimensions": {"type": "object"},
|
|
20
|
+
"count": {"type": "integer", "minimum": 1},
|
|
21
|
+
"error_count": {"type": "integer", "minimum": 0},
|
|
22
|
+
"error_rate": {"type": "number", "minimum": 0, "maximum": 1},
|
|
23
|
+
"duration_ms": {
|
|
24
|
+
"type": "object",
|
|
25
|
+
"required": ["total", "min", "max", "average"]
|
|
26
|
+
},
|
|
27
|
+
"histogram": {"type": "array", "maxItems": 20},
|
|
28
|
+
"breakdown_ms": {"type": "object"},
|
|
29
|
+
"signals": {"type": "object"},
|
|
30
|
+
"status_codes": {"type": "object"}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -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"]},
|
|
23
|
+
"event_type": {"enum": ["exception", "request", "query", "job", "cache", "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,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://chronos.example/schemas/sidekiq-job-v1.schema.json",
|
|
4
|
+
"title": "Chronos Sidekiq job payload v1",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": ["kind", "class", "queue", "duration_ms", "status"],
|
|
7
|
+
"properties": {
|
|
8
|
+
"kind": {"const": "sidekiq"},
|
|
9
|
+
"class": {"type": "string"},
|
|
10
|
+
"queue": {"type": "string"},
|
|
11
|
+
"jid": {"type": "string"},
|
|
12
|
+
"duration_ms": {"type": "number", "minimum": 0},
|
|
13
|
+
"queue_latency_ms": {"type": ["number", "null"], "minimum": 0},
|
|
14
|
+
"retry_count": {"type": "integer", "minimum": 0},
|
|
15
|
+
"arguments": {"type": "array", "maxItems": 20},
|
|
16
|
+
"arguments_truncated": {"type": "boolean"},
|
|
17
|
+
"tags": {"type": "array", "maxItems": 20},
|
|
18
|
+
"status": {"enum": ["completed", "failed"]},
|
|
19
|
+
"error_class": {"type": "string"}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# ADR-014 — Sidekiq context in the job envelope
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Accepted for version 0.6.
|
|
6
|
+
|
|
7
|
+
## Context
|
|
8
|
+
|
|
9
|
+
Sidekiq clients and servers usually run in different processes. Chronos needs correlation without changing the worker's public arguments, opening per-job resources, or allowing nested Active Job and Sidekiq hooks to duplicate the same exception.
|
|
10
|
+
|
|
11
|
+
## Decision
|
|
12
|
+
|
|
13
|
+
Use Sidekiq 4/5 public client and server middleware. Store a versioned `chronos` object beside `args`, containing only enqueue time, trace ID, and request ID. Never append metadata to `args`. On the server, establish a job execution context with a shared exception-deduplication map, emit bounded job telemetry, notify failures through `notify_once`, and re-raise the original exception. Do not install a global Sidekiq error handler.
|
|
14
|
+
|
|
15
|
+
Limit job arguments before the common sanitizer and serializer: 20 top-level arguments, 20 items per collection, depth four, and 512 bytes per string. Sanitization remains mandatory before queueing, retry, backlog, or transport.
|
|
16
|
+
|
|
17
|
+
## Alternatives
|
|
18
|
+
|
|
19
|
+
Appending a context argument was rejected because it changes worker arity and application-visible data. A process-global context was rejected because concurrent jobs would leak correlation. A global error handler plus server middleware was rejected because it creates duplicate capture paths. Per-job delivery threads or Redis connections were rejected because lifecycle and resource ownership belong to Sidekiq and the existing bounded agent.
|
|
20
|
+
|
|
21
|
+
## Positive consequences
|
|
22
|
+
|
|
23
|
+
Worker signatures remain compatible, cross-process correlation is bounded, nested integrations share deduplication, and Sidekiq retains retry semantics.
|
|
24
|
+
|
|
25
|
+
## Negative consequences
|
|
26
|
+
|
|
27
|
+
The Sidekiq envelope grows slightly, only two context identifiers propagate, and automatic argument collection still requires application privacy review.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# ADR-015 — Bounded local APM aggregation
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Accepted for version 0.7.
|
|
6
|
+
|
|
7
|
+
## Context
|
|
8
|
+
|
|
9
|
+
Sending every request, SQL query, and job as an independent event increases network overhead. Retaining every observation for client-side percentiles or unbounded N+1 analysis would transfer that cost to application memory.
|
|
10
|
+
|
|
11
|
+
## Decision
|
|
12
|
+
|
|
13
|
+
Aggregate request, query, and job observations by bounded low-cardinality dimensions. Store only counters, error counters, duration sum/min/max, fixed histogram buckets, component totals, status counters, and heuristic signal counters. Calculate averages locally and percentiles in the SaaS.
|
|
14
|
+
|
|
15
|
+
Use a fixed group limit, fixed query-fingerprint limit per trace, fixed batch size, and no new timer thread. Drain on observation threshold, explicit flush, and close. Clear incomplete trace trackers during drain. Normalize SQL comments and literal values before fingerprinting and never read binds. Use a `metric_batch` event through the existing sanitization, queue, retry, circuit breaker, and backlog pipeline.
|
|
16
|
+
|
|
17
|
+
## Alternatives
|
|
18
|
+
|
|
19
|
+
One event per observation was rejected as the default because delivery overhead scales directly with traffic. Retaining raw duration arrays was rejected because memory would scale with traffic. Client-side percentiles, SQL parsing dependencies, and background flush threads were rejected for the legacy line. Full SQL and bind capture was rejected for privacy and cardinality.
|
|
20
|
+
|
|
21
|
+
## Positive consequences
|
|
22
|
+
|
|
23
|
+
Delivery volume is reduced, memory remains bounded, request breakdown is available, SQL values are excluded, and the SaaS receives stable histograms suitable for percentile calculation.
|
|
24
|
+
|
|
25
|
+
## Negative consequences
|
|
26
|
+
|
|
27
|
+
Process crashes can lose undrained aggregates, incomplete trackers are discarded on drain, local signals are heuristic, and a defensive SQL normalizer cannot understand every database dialect.
|
data/docs/architecture.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Architecture
|
|
2
2
|
|
|
3
|
-
Chronos Ruby 0.
|
|
3
|
+
Chronos Ruby 0.7 uses hexagonal boundaries so the legacy core remains independent of frameworks and delivery infrastructure.
|
|
4
4
|
|
|
5
5
|
```mermaid
|
|
6
6
|
flowchart TB
|
|
@@ -16,7 +16,11 @@ flowchart TB
|
|
|
16
16
|
Context --> ThreadLocal[Adapters / ThreadLocalContextStore]
|
|
17
17
|
Rails[Chronos Rails / Railtie and subscribers] --> Facade
|
|
18
18
|
Rails --> Notifications[ActiveSupport Notifications]
|
|
19
|
+
Sidekiq[Integrations / Sidekiq client and server middleware] --> Facade
|
|
20
|
+
Sidekiq --> Envelope[Versioned job-envelope context]
|
|
19
21
|
Application --> Telemetry[Core / TelemetryEvent]
|
|
22
|
+
Telemetry --> APM[Application / ApmAggregator]
|
|
23
|
+
APM --> Metrics[Core / MetricAggregate and SqlNormalizer]
|
|
20
24
|
```
|
|
21
25
|
|
|
22
26
|
## Boundaries
|
|
@@ -28,6 +32,7 @@ flowchart TB
|
|
|
28
32
|
- Internal contains private concurrency and diagnostic mechanisms.
|
|
29
33
|
- Integrations contain optional framework entry points and never enter the domain boundary.
|
|
30
34
|
- `Chronos::Rails` contains the optional Railtie, installer, generator, and public-notification adapters.
|
|
35
|
+
- `Chronos::Integrations::Sidekiq` contains optional Sidekiq 4/5 middleware and bounded job normalization.
|
|
31
36
|
|
|
32
37
|
The `Chronos` module is a thin facade. Rails, Rack, ActiveSupport, Sidekiq, and job libraries must not be required by the core.
|
|
33
38
|
|
|
@@ -41,6 +46,10 @@ An exception becomes an immutable notice. `Sanitizer` removes sensitive values b
|
|
|
41
46
|
|
|
42
47
|
Rails timings become immutable `TelemetryEvent` values. `CaptureTelemetry` applies the remote/local event policy, `TelemetrySerializer` sanitizes the allowlisted payload, and the resulting `SerializedEvent` enters the same delivery pipeline. Rails classes are loaded only through `chronos/rails`; the core never requires Rails or ActiveSupport.
|
|
43
48
|
|
|
49
|
+
Sidekiq client middleware writes a versioned, allowlisted trace/request context beside the job's public arguments. Server middleware restores a job scope, limits arguments and tags, emits a job observation, and routes a failure through the existing notice pipeline before re-raising it. Sidekiq retains queue, retry, thread, and connection lifecycle ownership.
|
|
50
|
+
|
|
51
|
+
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
|
+
|
|
44
53
|
## Failure policy
|
|
45
54
|
|
|
46
55
|
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
|
@@ -11,8 +11,16 @@ Chronos Ruby 0.x is the legacy line. Technical compatibility does not make an en
|
|
|
11
11
|
| 2.6.10 | Rails 5.2 | Best effort | Core CI and feature-detection contract; dedicated app gate incomplete |
|
|
12
12
|
| 2.7 and newer | None in 0.x | Unsupported | Belongs to transitional or modern lines |
|
|
13
13
|
|
|
14
|
+
| Ruby | Sidekiq integration | Status | Evidence |
|
|
15
|
+
|---|---|---|---|
|
|
16
|
+
| 2.2.10–2.6 | Sidekiq 4 / 5 | Best effort | Middleware unit/integration contracts; dedicated real-gem matrix pending |
|
|
17
|
+
|
|
14
18
|
Version 0.5 includes Rails 4.2 and 5.2 applications plus a dedicated matrix, but this document conservatively keeps the combinations at `Best effort` until all release-gate evidence, including fake-server payload validation, is green. Rails 5.0 uses the same feature-detected public APIs but does not yet have its own example application.
|
|
15
19
|
|
|
20
|
+
Version `0.6.0.pre.1` uses the public Sidekiq 4/5 middleware signatures and remains `Best effort` until dedicated jobs exercise both real gem versions across their valid Ruby combinations.
|
|
21
|
+
|
|
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
|
+
|
|
16
24
|
Status meanings:
|
|
17
25
|
|
|
18
26
|
- 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 | Local allowlist for supported event envelopes |
|
|
42
|
+
| `enabled_event_types` | Optional | exception, request, query, job, cache, 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,6 +48,15 @@
|
|
|
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 job observations into bounded metric batches |
|
|
52
|
+
| `apm_max_groups` | Optional | `200` | Maximum metric groups and active trace trackers retained locally |
|
|
53
|
+
| `apm_flush_count` | Optional | `100` | Aggregate observations accepted before a threshold drain |
|
|
54
|
+
| `apm_batch_size` | Optional | `50` | Metric groups per batch; hard maximum 50 |
|
|
55
|
+
| `apm_max_queries_per_request` | Optional | `100` | Query fingerprints tracked per trace for repetition signals |
|
|
56
|
+
| `apm_slow_query_threshold_ms` | Optional | `500.0` | Query duration that produces a slow-query signal and sampled source |
|
|
57
|
+
| `apm_long_transaction_threshold_ms` | Optional | `1000.0` | Transaction-labelled SQL duration that produces a signal |
|
|
58
|
+
| `apm_n_plus_one_threshold` | Optional | `5` | Repeated fingerprint count producing one possible-N+1 signal; minimum 2 |
|
|
59
|
+
| `apm_histogram_buckets` | Optional | Fixed millisecond boundaries | Increasing positive duration boundaries; at most 19 plus `+Inf` |
|
|
51
60
|
|
|
52
61
|
```ruby
|
|
53
62
|
Chronos.configure do |config|
|
|
@@ -67,6 +76,14 @@ Chronos.configure do |config|
|
|
|
67
76
|
config.breadcrumb_capacity = 20
|
|
68
77
|
config.rails_capture_in_test = false
|
|
69
78
|
config.rails_capture_in_console = false
|
|
79
|
+
config.apm_enabled = true
|
|
80
|
+
config.apm_max_groups = 200
|
|
81
|
+
config.apm_flush_count = 100
|
|
82
|
+
config.apm_batch_size = 50
|
|
83
|
+
config.apm_max_queries_per_request = 100
|
|
84
|
+
config.apm_slow_query_threshold_ms = 500.0
|
|
85
|
+
config.apm_long_transaction_threshold_ms = 1000.0
|
|
86
|
+
config.apm_n_plus_one_threshold = 5
|
|
70
87
|
end
|
|
71
88
|
```
|
|
72
89
|
|
data/docs/data-collected.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Data collected
|
|
2
2
|
|
|
3
|
-
Version 0.
|
|
3
|
+
Version 0.7 emits exceptions, individual cache telemetry, and aggregated request/query/job 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
|
|---|---|---|
|
|
@@ -27,9 +27,23 @@ Version 0.5 emits exception, request, query, job, and cache events. All fields p
|
|
|
27
27
|
| SQL operation name, cached flag, duration | Collected; SQL text omitted | `sql.active_record` |
|
|
28
28
|
| Mailer/action and duration | Collected; message content omitted | `deliver.action_mailer` |
|
|
29
29
|
| Active Job class, queue, duration | Collected when available; arguments omitted | `perform.active_job` |
|
|
30
|
+
| Sidekiq class, queue, JID, retry count, duration, status, error class | Collected with optional middleware | Sidekiq job envelope and local clock |
|
|
31
|
+
| Sidekiq queue latency | Collected when enqueue time is available | Sidekiq or Chronos envelope timestamp |
|
|
32
|
+
| Sidekiq arguments | Collected, sanitized, and bounded | First 20 job arguments; collections/depth/strings limited |
|
|
33
|
+
| Sidekiq tags | Collected and bounded | Job payload or public worker options |
|
|
34
|
+
| Sidekiq trace/request IDs | Propagated when present; trace generated otherwise | Chronos job-envelope metadata |
|
|
35
|
+
| APM counts, error counts/rates, duration total/min/max/average | Aggregated by default | Request, query, and job observations |
|
|
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 |
|
|
38
|
+
| Normalized SQL and SHA-256 fingerprint | Collected without comments, literals, or binds | `sql.active_record` payload |
|
|
39
|
+
| SQL adapter, operation, inferred table, AR name, cache flag, role/shard | Collected when exposed | Public notification payload and connection feature detection |
|
|
40
|
+
| Slow SQL source frame | Collected only for threshold-selected slow queries | Bounded application call frame |
|
|
41
|
+
| APM diagnostic signals | Heuristic counters | Local threshold and repetition detection |
|
|
30
42
|
| Cache operation, store, hit flag, duration | Collected; key/value omitted | ActiveSupport cache notifications |
|
|
31
43
|
|
|
32
|
-
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,
|
|
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 installed gems. Sidekiq JIDs and bounded arguments are the explicit version 0.6 exception to the earlier job-ID/argument exclusion.
|
|
45
|
+
|
|
46
|
+
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.
|
|
33
47
|
|
|
34
48
|
The secret `project_key` is an authentication header and is excluded from the JSON payload and logger diagnostics. The envelope field named `project_key` contains the public `project_id` required by the current v1 server contract.
|
|
35
49
|
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Essential APM aggregation
|
|
2
|
+
|
|
3
|
+
Version `0.7.0.pre.1` aggregates request, SQL, and job 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
|
+
|
|
5
|
+
## Request metrics
|
|
6
|
+
|
|
7
|
+
Request groups use normalized route and HTTP method. Status codes are counted inside the group so error rate can be calculated without making status part of an unbounded key. Each metric contains count, error count/rate, total, minimum, maximum, average, fixed histogram buckets, and component breakdown. Percentiles remain server-side because retaining every duration locally would violate the memory boundary.
|
|
8
|
+
|
|
9
|
+
Rack records request metrics for non-Rails applications. Rails controller notifications and Rack share `record_event_once`, so the same request is counted only once. Controller notification data wins when available because its route is more precise.
|
|
10
|
+
|
|
11
|
+
## SQL metrics and signals
|
|
12
|
+
|
|
13
|
+
`Chronos::Core::SqlNormalizer` removes block/line comments, quoted literal values, numeric values, booleans, nulls, and repeated `IN` values before producing a SHA-256 fingerprint. Binds are never read. Query dimensions can contain adapter, operation, inferred table, bounded normalized query, fingerprint, Active Record operation name, cache flag, connection role/shard, and a bounded source frame for slow sampled queries.
|
|
14
|
+
|
|
15
|
+
Local signals are intentionally heuristic:
|
|
16
|
+
|
|
17
|
+
- `slow_query` when duration reaches `apm_slow_query_threshold_ms`;
|
|
18
|
+
- `repeated_query` after the same fingerprint appears again in one trace;
|
|
19
|
+
- `possible_n_plus_one` once when the configured repetition threshold is reached;
|
|
20
|
+
- `long_transaction` for transaction-labelled SQL over its threshold;
|
|
21
|
+
- `connection_error` and `deadlock` from bounded exception class names.
|
|
22
|
+
|
|
23
|
+
The SaaS must confirm and correlate these signals. They are not proof of an N+1, deadlock, or application defect.
|
|
24
|
+
|
|
25
|
+
## Bounded state
|
|
26
|
+
|
|
27
|
+
- at most `apm_max_groups` metric groups;
|
|
28
|
+
- at most `apm_max_groups` active trace trackers;
|
|
29
|
+
- at most `apm_max_queries_per_request` fingerprints per trace;
|
|
30
|
+
- at most 19 configured histogram boundaries plus `+Inf`;
|
|
31
|
+
- at most `apm_batch_size` groups per payload, with a hard maximum of 50;
|
|
32
|
+
- trackers are removed when their request completes and all remaining trackers are cleared on aggregate drain.
|
|
33
|
+
|
|
34
|
+
New groups beyond capacity are dropped and counted in `dropped_groups`. Existing groups continue accumulating. The state is process-local and is lost on restart.
|
|
35
|
+
|
|
36
|
+
## Breakdown
|
|
37
|
+
|
|
38
|
+
The contract supports `database`, `view`, `external_http`, `cache`, `queue`, `application`, and `unknown`. Version 0.7 fills database/view/cache within a traced request, queue/application for jobs, and residual application time for requests. External HTTP instrumentation begins in version 0.8.
|
|
39
|
+
|
|
40
|
+
## Configuration
|
|
41
|
+
|
|
42
|
+
```ruby
|
|
43
|
+
Chronos.configure do |config|
|
|
44
|
+
# connection settings omitted
|
|
45
|
+
config.apm_enabled = true
|
|
46
|
+
config.apm_max_groups = 200
|
|
47
|
+
config.apm_flush_count = 100
|
|
48
|
+
config.apm_batch_size = 50
|
|
49
|
+
config.apm_max_queries_per_request = 100
|
|
50
|
+
config.apm_slow_query_threshold_ms = 500.0
|
|
51
|
+
config.apm_long_transaction_threshold_ms = 1000.0
|
|
52
|
+
config.apm_n_plus_one_threshold = 5
|
|
53
|
+
config.apm_histogram_buckets = [5.0, 10.0, 25.0, 50.0, 100.0, 250.0, 500.0, 1000.0]
|
|
54
|
+
end
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Setting `apm_enabled = false` restores individual request/query/job telemetry for compatibility diagnostics. Cache events remain individual in 0.7 while also contributing to an existing request breakdown.
|
|
@@ -7,3 +7,5 @@ This module is separate from capture because configuration errors should be foun
|
|
|
7
7
|
Risks include accidentally logging credentials and changing settings while events run. The snapshot prevents mutation, while logger and transport code never interpolate `project_key`.
|
|
8
8
|
|
|
9
9
|
Tests in `spec/unit/configuration_spec.rb` verify required fields, HTTPS defaults, immutable containers, disabled operation, and bounded numeric settings.
|
|
10
|
+
|
|
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).
|
|
@@ -57,4 +57,4 @@ The repository contains independent applications under `examples/rails-4.2` and
|
|
|
57
57
|
|
|
58
58
|
## Limits
|
|
59
59
|
|
|
60
|
-
Version 0.
|
|
60
|
+
Version 0.7 aggregates controller, SQL, and job timings into bounded APM batches. SQL literals and binds remain excluded while a bounded normalized query and fingerprint are produced. Sidekiq support remains a separate optional integration; full Active Job propagation remains a later legacy increment.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Sidekiq 4/5 legacy integration
|
|
2
|
+
|
|
3
|
+
Version `0.6.0.pre.1` starts the legacy jobs line with optional Sidekiq 4 and 5 client and server middleware. Load it after declaring Sidekiq:
|
|
4
|
+
|
|
5
|
+
```ruby
|
|
6
|
+
gem "sidekiq", "~> 5.0"
|
|
7
|
+
gem "chronos-ruby", "0.7.0.pre.1", :require => "chronos/sidekiq"
|
|
8
|
+
```
|
|
9
|
+
|
|
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.
|
|
11
|
+
|
|
12
|
+
The client middleware adds a top-level `chronos` metadata object to the Sidekiq envelope. It never changes the public `args` array. Only `trace_id` and `request_id` propagate, with schema version and enqueue time. The server scopes that context for the worker, measures duration and calculable queue latency, and emits one `job` event.
|
|
13
|
+
|
|
14
|
+
Collected Sidekiq fields are worker class, queue, JID, retry count, duration, queue latency, status, error class, bounded tags, and bounded arguments. At most 20 top-level arguments, 20 values per nested collection, four levels, and 512 bytes per string are traversed. Arguments then pass through the standard sensitive-key/content sanitizer before queueing. Limits reduce exposure and resource use but do not make unnecessary personal data safe to collect.
|
|
15
|
+
|
|
16
|
+
On failure, the server middleware records a failed-job observation, invokes `notify_once`, and re-raises the identical exception so Sidekiq retains ownership of retries and failure handlers. A shared execution marker prevents a nested Active Job hook and the Sidekiq middleware from sending the same exception twice. Version 0.7 aggregates the job observation; the exception retains sanitized bounded arguments. Chronos does not install an additional global Sidekiq error handler.
|
|
17
|
+
|
|
18
|
+
Known limitations for this first 0.6 prerelease:
|
|
19
|
+
|
|
20
|
+
- the compatibility contract uses Sidekiq 4/5 public middleware signatures; dedicated real Sidekiq matrix jobs must pass before status becomes `Supported`;
|
|
21
|
+
- Active Job propagation, Resque, and Delayed Job are subsequent 0.6 increments;
|
|
22
|
+
- argument collection is automatic in this prerelease; applications should avoid placing secrets or unnecessary personal data in job arguments;
|
|
23
|
+
- context propagation is limited to trace and request identifiers.
|
|
@@ -6,4 +6,4 @@ Telemetry has the same `schema_version`, event ID, timestamps, project, environm
|
|
|
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.7 aggregates request, query, and job observations into `metric_batch` events by default. Cache remains an individual event while contributing to an existing traced request breakdown. 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.7 makes no unverified speed claim.
|
|
4
4
|
|
|
5
5
|
Current controls:
|
|
6
6
|
|
|
@@ -19,6 +19,8 @@ Current controls:
|
|
|
19
19
|
- request context and breadcrumbs have fixed structural and byte limits;
|
|
20
20
|
- Rack middleware never consumes request or response bodies.
|
|
21
21
|
- Rails subscribers copy only small allowlisted field sets and never copy raw SQL or job arguments.
|
|
22
|
+
- Sidekiq middleware creates no per-job thread or connection and bounds arguments, collections, nesting, strings, and tags before telemetry capture.
|
|
23
|
+
- APM group, trace, query-fingerprint, histogram, and batch counts are fixed; no APM timer thread is created.
|
|
22
24
|
|
|
23
25
|
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.
|
|
24
26
|
|
|
@@ -76,3 +78,25 @@ ITERATIONS=100000 bundle _1.17.3_ exec ruby benchmarks/request_overhead.rb
|
|
|
76
78
|
```
|
|
77
79
|
|
|
78
80
|
A local diagnostic run on 2026-07-20 used Ruby 2.2.10 on macOS arm64 and 10,000 successful Rack-protocol calls. The direct application calls took 0.013272 seconds and middleware calls took 0.539758 seconds, for an estimated 52.649 microseconds of middleware work per request. The fixture uses no network, error capture, or response-body enumeration. This is a single development measurement, not a production latency claim; controlled warmup, median, and dispersion remain required before publishing a performance claim.
|
|
81
|
+
|
|
82
|
+
## Version 0.6 Sidekiq middleware benchmark
|
|
83
|
+
|
|
84
|
+
Run:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
ITERATIONS=100000 bundle _1.17.3_ exec ruby benchmarks/sidekiq_middleware.rb
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
The benchmark executes client context injection and successful server normalization with a no-op notifier. It includes bounded argument handling and clock reads, but excludes Sidekiq/Redis, serialization, queueing, and network delivery. Record a controlled result before making a performance claim.
|
|
91
|
+
|
|
92
|
+
## Version 0.7 APM aggregation benchmark
|
|
93
|
+
|
|
94
|
+
Run:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
ITERATIONS=100000 bundle _1.17.3_ exec ruby benchmarks/apm_aggregation.rb
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
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
|
+
|
|
102
|
+
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.
|
data/docs/privacy-lgpd.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Privacy and LGPD
|
|
2
2
|
|
|
3
|
-
Version 0.
|
|
3
|
+
Version 0.7 sanitizes exception, framework telemetry, 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
|
|
|
@@ -13,14 +13,24 @@ Version 0.5 sanitizes exception and framework telemetry before JSON serializatio
|
|
|
13
13
|
| Payment-card candidates that pass the Luhn check | Replaced with `[FILTERED_CARD]` |
|
|
14
14
|
| IPv4 addresses | Last octet replaced with `0` |
|
|
15
15
|
| Unknown Ruby objects | Represented by class name without calling application serialization |
|
|
16
|
-
| Request/response bodies, raw query strings, cookies, authorization headers, raw SQL/binds, cache values, mail bodies,
|
|
16
|
+
| Request/response bodies, raw query strings, cookies, authorization headers, raw SQL/binds, cache values, mail bodies, environment variables | Never collected automatically |
|
|
17
|
+
| Sidekiq arguments | Collected automatically, limited before sanitization, then redacted by the common policy |
|
|
18
|
+
| SQL | Comments, quoted/numeric/boolean/null literals removed; binds never read; bounded identifiers remain |
|
|
17
19
|
|
|
18
|
-
The retry backlog exists only in process memory, accepts only `SerializedEvent`, has a fixed capacity, and disappears on process exit. Version 0.
|
|
20
|
+
The retry backlog exists only in process memory, accepts only `SerializedEvent`, has a fixed capacity, and disappears on process exit. Version 0.7 does not persist telemetry to disk.
|
|
19
21
|
|
|
20
22
|
## Rails telemetry
|
|
21
23
|
|
|
22
24
|
Rails subscribers use per-notification allowlists. SQL events retain only the operation name, cached flag, and duration; cache events omit key and value; mailer events omit addresses and content; Active Job events omit job ID and arguments; view identifiers are reduced to basenames. Controller parameters are sanitized by the normal payload pipeline before queueing.
|
|
23
25
|
|
|
26
|
+
## Sidekiq jobs
|
|
27
|
+
|
|
28
|
+
The optional Sidekiq middleware is the only version 0.6 integration that automatically reads job arguments. It traverses at most 20 top-level arguments, 20 items per nested collection, four levels, and 512 bytes per string. These structural limits run before the common key and content sanitizer. Trace propagation contains only trace and request identifiers. Do not place credentials or unnecessary personal, health, or financial data in job arguments; configure application-specific blocklist keys and audit representative synthetic payloads before enabling production delivery.
|
|
29
|
+
|
|
30
|
+
## APM dimensions
|
|
31
|
+
|
|
32
|
+
Metric groups deliberately exclude user IDs, JIDs, raw URLs, request parameters, bind values, exception messages, and cache keys. SQL normalization removes common literal forms and comments before fingerprinting, but retains bounded database identifiers and cannot parse every dialect. Do not encode personal or secret values in schema, table, column, SQL keyword, or operation names. Slow-query source contains a bounded file/line frame under the configured application root, not source-code contents.
|
|
33
|
+
|
|
24
34
|
## Rack context and breadcrumbs
|
|
25
35
|
|
|
26
36
|
The Rack middleware copies only bounded operational fields and parameter hashes that another component already parsed. It does not read `rack.input` or copy `QUERY_STRING`. User context is opt-in through `chronos.user`, and user agent collection is disabled unless the middleware option enables it.
|