chronos-ruby 0.9.0.pre.4 → 1.1.0
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 +36 -0
- data/README.md +108 -197
- data/contracts/apm-batch-v1.schema.json +51 -1
- data/docs/adr/ADR-007-feature-detection.md +25 -0
- data/docs/adr/ADR-008-context-store.md +25 -0
- data/docs/adr/ADR-009-sampling.md +25 -0
- data/docs/adr/ADR-010-opentelemetry-interoperability.md +25 -0
- data/docs/adr/ADR-015-bounded-apm-aggregation.md +3 -3
- data/docs/adr/ADR-018-pre-1.0-hardening.md +6 -2
- data/docs/adr/ADR-019-bounded-query-diagnostics.md +44 -0
- data/docs/architecture.md +5 -2
- data/docs/compatibility.md +30 -23
- data/docs/configuration.md +21 -0
- data/docs/data-collected.md +9 -3
- data/docs/deprecation-policy.md +1 -1
- data/docs/examples/plain-ruby.md +6 -0
- data/docs/migration-from-airbrake.md +1 -1
- data/docs/modules/apm-aggregation.md +18 -5
- data/docs/modules/breadcrumbs.md +23 -0
- data/docs/modules/context.md +21 -0
- data/docs/modules/deploys.md +23 -0
- data/docs/modules/job-monitoring.md +22 -0
- data/docs/modules/request-monitoring.md +20 -0
- data/docs/modules/runtime-metrics.md +22 -0
- data/docs/modules/sampling.md +22 -0
- data/docs/modules/sidekiq-legacy.md +1 -1
- data/docs/modules/sql-monitoring.md +76 -0
- data/docs/modules/telemetry-events.md +1 -1
- data/docs/performance.md +30 -3
- data/docs/privacy-lgpd.md +6 -3
- data/docs/protocol-v1.md +2 -2
- data/docs/release-1.0-readiness.md +17 -15
- data/docs/release-1.1-readiness.md +51 -0
- data/docs/security-review.md +7 -3
- data/docs/troubleshooting.md +6 -0
- data/lib/chronos/agent.rb +12 -2
- data/lib/chronos/application/apm_aggregator.rb +179 -29
- data/lib/chronos/configuration/apm_validation.rb +51 -1
- data/lib/chronos/configuration.rb +17 -1
- data/lib/chronos/core/metric_aggregate.rb +69 -7
- data/lib/chronos/core/sql_query_analyzer.rb +309 -0
- data/lib/chronos/ports/query_inspector.rb +23 -0
- data/lib/chronos/rails/active_record_query_inspector.rb +235 -0
- data/lib/chronos/rails/notifications_subscriber.rb +163 -2
- data/lib/chronos/rails.rb +1 -0
- data/lib/chronos/version.rb +1 -1
- data/lib/chronos.rb +2 -0
- metadata +21 -4
|
@@ -24,10 +24,60 @@
|
|
|
24
24
|
"type": "object",
|
|
25
25
|
"required": ["total", "min", "max", "average"]
|
|
26
26
|
},
|
|
27
|
+
"percentiles_ms": {
|
|
28
|
+
"type": "object",
|
|
29
|
+
"additionalProperties": false,
|
|
30
|
+
"required": ["p50", "p95", "p99"],
|
|
31
|
+
"properties": {
|
|
32
|
+
"p50": {"type": "number", "minimum": 0},
|
|
33
|
+
"p95": {"type": "number", "minimum": 0},
|
|
34
|
+
"p99": {"type": "number", "minimum": 0}
|
|
35
|
+
}
|
|
36
|
+
},
|
|
27
37
|
"histogram": {"type": "array", "maxItems": 20},
|
|
28
38
|
"breakdown_ms": {"type": "object"},
|
|
29
39
|
"signals": {"type": "object"},
|
|
30
|
-
"status_codes": {"type": "object"}
|
|
40
|
+
"status_codes": {"type": "object"},
|
|
41
|
+
"severity_counts": {
|
|
42
|
+
"type": "object",
|
|
43
|
+
"additionalProperties": false,
|
|
44
|
+
"properties": {
|
|
45
|
+
"error": {"type": "integer", "minimum": 0},
|
|
46
|
+
"warning": {"type": "integer", "minimum": 0},
|
|
47
|
+
"info": {"type": "integer", "minimum": 0},
|
|
48
|
+
"suggestion": {"type": "integer", "minimum": 0}
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"diagnostics": {
|
|
52
|
+
"type": "array",
|
|
53
|
+
"maxItems": 20,
|
|
54
|
+
"items": {
|
|
55
|
+
"type": "object",
|
|
56
|
+
"additionalProperties": false,
|
|
57
|
+
"required": ["code", "severity", "category", "message", "evidence", "count"],
|
|
58
|
+
"properties": {
|
|
59
|
+
"code": {"type": "string", "maxLength": 128},
|
|
60
|
+
"severity": {"enum": ["error", "warning", "info", "suggestion"]},
|
|
61
|
+
"category": {"type": "string", "maxLength": 64},
|
|
62
|
+
"message": {"type": "string", "maxLength": 512},
|
|
63
|
+
"recommendation": {"type": "string", "maxLength": 512},
|
|
64
|
+
"evidence": {"type": "object"},
|
|
65
|
+
"count": {"type": "integer", "minimum": 1}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
"query_analysis": {"type": "object"},
|
|
70
|
+
"tracking": {
|
|
71
|
+
"type": "object",
|
|
72
|
+
"additionalProperties": false,
|
|
73
|
+
"required": ["active_traces", "dropped_trace_trackers", "expired_trace_trackers", "dropped_query_fingerprints"],
|
|
74
|
+
"properties": {
|
|
75
|
+
"active_traces": {"type": "integer", "minimum": 0},
|
|
76
|
+
"dropped_trace_trackers": {"type": "integer", "minimum": 0},
|
|
77
|
+
"expired_trace_trackers": {"type": "integer", "minimum": 0},
|
|
78
|
+
"dropped_query_fingerprints": {"type": "integer", "minimum": 0}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
31
81
|
}
|
|
32
82
|
}
|
|
33
83
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# ADR-007 — Feature detection nas integrações
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Aceito para 1.0.
|
|
6
|
+
|
|
7
|
+
## Contexto
|
|
8
|
+
|
|
9
|
+
Rails 4.2/5.2, Active Job e Sidekiq 4/5 expõem conjuntos diferentes de constantes e hooks. Comparar apenas números de versão cria falsos positivos em instalações parciais.
|
|
10
|
+
|
|
11
|
+
## Decisão
|
|
12
|
+
|
|
13
|
+
Integrações opcionais verificam a presença da biblioteca e das APIs públicas necessárias antes de instalar middleware, subscribers ou extensões. A instalação é idempotente e não exige Zeitwerk.
|
|
14
|
+
|
|
15
|
+
## Alternativas
|
|
16
|
+
|
|
17
|
+
Branches por versão e uso de APIs privadas foram rejeitados por fragilidade e custo de manutenção.
|
|
18
|
+
|
|
19
|
+
## Consequências positivas
|
|
20
|
+
|
|
21
|
+
O núcleo permanece carregável em Ruby puro e combinações validadas compartilham adapters menores.
|
|
22
|
+
|
|
23
|
+
## Consequências negativas
|
|
24
|
+
|
|
25
|
+
Cada caminho detectado exige contrato e aplicação de exemplo; uma biblioteca que imite parcialmente a API pode precisar de tratamento dedicado.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# ADR-008 — Context store por runtime
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Aceito para 1.0 legado.
|
|
6
|
+
|
|
7
|
+
## Contexto
|
|
8
|
+
|
|
9
|
+
Requests e jobs concorrentes não podem compartilhar usuário, parâmetros, breadcrumbs ou trace ID, mas Ruby 2.2 não oferece uma estratégia fiber-local moderna uniforme.
|
|
10
|
+
|
|
11
|
+
## Decisão
|
|
12
|
+
|
|
13
|
+
Definir uma porta de context store e usar armazenamento thread-local na linha 0.x/1.0 legado. Todo escopo restaura o valor anterior e limpa em `ensure`; somente IDs permitidos atravessam processos.
|
|
14
|
+
|
|
15
|
+
## Alternativas
|
|
16
|
+
|
|
17
|
+
Estado global foi rejeitado por vazamento entre execuções. Fiber local foi adiado para a linha moderna.
|
|
18
|
+
|
|
19
|
+
## Consequências positivas
|
|
20
|
+
|
|
21
|
+
O isolamento é testável e o núcleo não depende da primitiva concreta.
|
|
22
|
+
|
|
23
|
+
## Consequências negativas
|
|
24
|
+
|
|
25
|
+
Threads e fibers criadas pela aplicação exigem propagação explícita; adapters futuros precisam preservar a mesma porta.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# ADR-009 — Sampling limitado localmente
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Aceito para 1.0.
|
|
6
|
+
|
|
7
|
+
## Contexto
|
|
8
|
+
|
|
9
|
+
O agente precisa controlar volume durante carga alta e aceitar redução remota sem permitir expansão inesperada da coleta.
|
|
10
|
+
|
|
11
|
+
## Decisão
|
|
12
|
+
|
|
13
|
+
Usar `sampling_rate` local como teto. Configuração remota pode somente reduzir a taxa, desabilitar tipos ou ativar kill switch. As opções são allowlisted, limitadas e nunca incluem código/regex.
|
|
14
|
+
|
|
15
|
+
## Alternativas
|
|
16
|
+
|
|
17
|
+
Sampling exclusivamente no servidor desperdiça transporte. Sampling remoto sem teto local foi rejeitado por privacidade e previsibilidade.
|
|
18
|
+
|
|
19
|
+
## Consequências positivas
|
|
20
|
+
|
|
21
|
+
O operador conserva controle e a decisão ocorre antes de HTTP/retry.
|
|
22
|
+
|
|
23
|
+
## Consequências negativas
|
|
24
|
+
|
|
25
|
+
Sampling uniforme pode perder eventos raros; análises devem considerar a taxa efetiva.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# ADR-010 — Interoperabilidade futura com OpenTelemetry
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Adiado; limite aceito para 1.0 legado.
|
|
6
|
+
|
|
7
|
+
## Contexto
|
|
8
|
+
|
|
9
|
+
O Chronos precisa correlacionar trace/request sem duplicar SDKs ou impor dependências modernas a Ruby 2.2–2.6.
|
|
10
|
+
|
|
11
|
+
## Decisão
|
|
12
|
+
|
|
13
|
+
Manter IDs de correlação e portas independentes do fornecedor na 1.0. Não depender de OpenTelemetry nem instalar instrumentação global na linha legado. Uma ponte opcional será projetada na linha transitional/modern e deverá traduzir somente campos permitidos.
|
|
14
|
+
|
|
15
|
+
## Alternativas
|
|
16
|
+
|
|
17
|
+
Adicionar o SDK como dependência obrigatória foi rejeitado por incompatibilidade e overhead. Copiar spans completos foi rejeitado por cardinalidade e privacidade.
|
|
18
|
+
|
|
19
|
+
## Consequências positivas
|
|
20
|
+
|
|
21
|
+
O protocolo v1 permanece estável e aplicações legadas não recebem novas dependências.
|
|
22
|
+
|
|
23
|
+
## Consequências negativas
|
|
24
|
+
|
|
25
|
+
Não há propagação automática com ecossistemas OpenTelemetry na 1.0; integrações futuras exigirão contrato e matriz próprios.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Status
|
|
4
4
|
|
|
5
|
-
Accepted for version 0.7.
|
|
5
|
+
Accepted for version 0.7; trace-drain behavior amended by ADR-019.
|
|
6
6
|
|
|
7
7
|
## Context
|
|
8
8
|
|
|
@@ -12,7 +12,7 @@ Sending every request, SQL query, and job as an independent event increases netw
|
|
|
12
12
|
|
|
13
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
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.
|
|
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. ADR-019 later preserves incomplete trace trackers across drains under capacity and idle-TTL limits. 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
16
|
|
|
17
17
|
## Alternatives
|
|
18
18
|
|
|
@@ -24,4 +24,4 @@ Delivery volume is reduced, memory remains bounded, request breakdown is availab
|
|
|
24
24
|
|
|
25
25
|
## Negative consequences
|
|
26
26
|
|
|
27
|
-
Process crashes can lose undrained aggregates,
|
|
27
|
+
Process crashes can lose undrained aggregates, idle/over-capacity trackers can be discarded and are counted, local signals are heuristic, and a defensive SQL normalizer cannot understand every database dialect.
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
# ADR-018: Pre-1.0 hardening gates
|
|
2
2
|
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Concluído pela versão 1.0.0.
|
|
6
|
+
|
|
3
7
|
## Decision
|
|
4
8
|
|
|
5
|
-
Keep the release
|
|
9
|
+
Keep the release in prerelease while any mandatory 1.0 evidence remains external or incomplete. Promote only after bounded local ignore rules, Active Job envelope propagation, real Sidekiq compatibility jobs, repeatable comparative/load benchmarks, and explicit release/security policies are present and green.
|
|
6
10
|
|
|
7
11
|
## Consequences
|
|
8
12
|
|
|
9
|
-
The
|
|
13
|
+
The complete candidate matrix passed before the 1.0 promotion. Active Job has one namespaced serialized field without changing arguments. Application callbacks remain bounded in count but their execution cost belongs to the application. Trusted Publishing, package checksums and SBOMs are used until a trusted signing lifecycle is available.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# ADR-019 — Bounded query diagnostics and opt-in database inspection
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Accepted.
|
|
6
|
+
|
|
7
|
+
## Context
|
|
8
|
+
|
|
9
|
+
Fingerprint repetition and duration identify useful SQL symptoms but do not tell the consumer which access columns were observed, whether an existing index covers them, or what the database planner estimated. Running deep analysis inside a legacy application can add latency, expose data, increase cardinality, and violate the fixed-memory requirement.
|
|
10
|
+
|
|
11
|
+
## Decision
|
|
12
|
+
|
|
13
|
+
Analyze normalized SELECT text by default with a dependency-free bounded heuristic. Emit structured diagnostics with stable code, severity (`error`, `warning`, `info`, `suggestion`), category, bounded evidence, count, and optional recommendation.
|
|
14
|
+
|
|
15
|
+
Define `Ports::QueryInspector` and keep its ActiveRecord implementation in `Chronos::Rails`. Index, statistics, and plan inspection are independent explicit opt-ins. Inspect each eligible fingerprint at most once per subscriber, cap inspected fingerprints, and require a duration threshold. Plans use `EXPLAIN` only, never `EXPLAIN ANALYZE`; DDL and automatic index creation are prohibited. Retain only allowlisted schema/planner fields and exception class names. Never retain raw SQL, binds, plan predicates, arbitrary rows, or exception messages.
|
|
16
|
+
|
|
17
|
+
Preserve trace trackers across metric drains with capacity and idle TTL. Report loss counters. Measure outer transaction time with bounded per-connection notification state. Derive approximate p50/p95/p99 from fixed histograms without retaining duration samples.
|
|
18
|
+
|
|
19
|
+
Keep new metric fields optional in the v1 JSON Schema for backward compatibility, although the new agent emits them. Consumer models use diagnostic code/severity as stable fields and treat message text as a fallback presentation value.
|
|
20
|
+
|
|
21
|
+
## Alternatives
|
|
22
|
+
|
|
23
|
+
- Server-only static analysis was rejected because existing-index comparison requires local schema evidence and immediate signals remain useful.
|
|
24
|
+
- Automatic `EXPLAIN ANALYZE` was rejected because it executes the query.
|
|
25
|
+
- Automatic `CREATE INDEX` was rejected because it can block writes, consume storage, and regress mutation workloads.
|
|
26
|
+
- Shipping raw SQL/plans was rejected for privacy and cardinality.
|
|
27
|
+
- A full SQL-parser dependency was rejected for legacy compatibility, installation cost, and dialect complexity.
|
|
28
|
+
- Unbounded trace/inspection caches were rejected for memory safety.
|
|
29
|
+
|
|
30
|
+
## Positive consequences
|
|
31
|
+
|
|
32
|
+
- Consumers receive actionable, typed evidence with clear confidence limits.
|
|
33
|
+
- Default analysis adds no database round trip.
|
|
34
|
+
- Opt-in inspection is read-only, sampled by fingerprint/duration, and contains adapter failures.
|
|
35
|
+
- Errors, warnings, information, and suggestions can map directly to observer models.
|
|
36
|
+
- Trace correlation no longer disappears at every aggregate flush.
|
|
37
|
+
|
|
38
|
+
## Negative consequences
|
|
39
|
+
|
|
40
|
+
- Static parsing can miss complex SQL, aliases, expressions, partial indexes, and dialect features.
|
|
41
|
+
- Even non-executing `EXPLAIN` and catalog reads consume a connection/planner budget and have no portable legacy timeout.
|
|
42
|
+
- Index recommendations do not know true selectivity, write cost, storage, or production distribution.
|
|
43
|
+
- Approximate percentiles use histogram upper bounds and may be coarse.
|
|
44
|
+
- Transaction elapsed time is measured between notification callbacks, not database wire boundaries.
|
data/docs/architecture.md
CHANGED
|
@@ -20,7 +20,10 @@ flowchart TB
|
|
|
20
20
|
Sidekiq --> Envelope[Versioned job-envelope context]
|
|
21
21
|
Application --> Telemetry[Core / TelemetryEvent]
|
|
22
22
|
Telemetry --> APM[Application / ApmAggregator]
|
|
23
|
-
APM --> Metrics[Core / MetricAggregate and
|
|
23
|
+
APM --> Metrics[Core / MetricAggregate, SqlNormalizer, and SqlQueryAnalyzer]
|
|
24
|
+
Rails --> Inspector[ActiveRecordQueryInspector opt-in]
|
|
25
|
+
Inspector --> QueryPort[Ports / QueryInspector]
|
|
26
|
+
Inspector --> Metrics
|
|
24
27
|
NetHTTP[Explicit Net::HTTP instance wrapper] --> Facade
|
|
25
28
|
Rails --> Cache[Core / CacheNormalizer]
|
|
26
29
|
Application --> Dependencies[Application / DependencyReporter]
|
|
@@ -53,7 +56,7 @@ Rails timings become immutable `TelemetryEvent` values. `CaptureTelemetry` appli
|
|
|
53
56
|
|
|
54
57
|
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.
|
|
55
58
|
|
|
56
|
-
Version 0.7 routes request, query, and job observations through `ApmAggregator`. `SqlNormalizer` removes values before grouping,
|
|
59
|
+
Version 0.7 routes request, query, and job observations through `ApmAggregator`. `SqlNormalizer` removes values before grouping, `SqlQueryAnalyzer` derives bounded access evidence, and `MetricAggregate` owns fixed numerical statistics, approximate percentiles, severities, diagnostics, and one representative analysis. Active trace trackers survive group drains, expire by TTL, and expose loss counters. `ActiveRecordQueryInspector` is an optional Rails adapter behind `Ports::QueryInspector`; it reads public index metadata and allowlisted PostgreSQL/MySQL statistics/plans without `ANALYZE` or DDL. Threshold or lifecycle drains create `metric_batch` telemetry that passes through the existing sanitizer and delivery pipeline. No APM-specific thread is created.
|
|
57
60
|
|
|
58
61
|
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.
|
|
59
62
|
|
data/docs/compatibility.md
CHANGED
|
@@ -1,36 +1,43 @@
|
|
|
1
1
|
# Compatibility
|
|
2
2
|
|
|
3
|
-
Chronos Ruby
|
|
3
|
+
Chronos Ruby 1.1 is the current stable legacy line. Technical compatibility does not make an end-of-life Ruby, Rails, Rack, or Sidekiq release secure. The planned Ruby 2.7/Rails 6 transitional matrix remains deferred until it has dedicated CI and a real application gate.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|---|---|---|---|
|
|
7
|
-
| 2.2.10 | Rails 4.2 | Best effort | Core CI, Rails 4.2 example, dedicated smoke gate |
|
|
8
|
-
| 2.3.8 | Rails 4.2 / 5.0 | Best effort | Core CI and feature-detection contract; dedicated app gate incomplete |
|
|
9
|
-
| 2.4.10 | Rails 4.2 / 5.0 | Best effort | Core CI and feature-detection contract; dedicated app gate incomplete |
|
|
10
|
-
| 2.5.9 | Rails 5.2 | Best effort | Core CI, Rails 5.2 example, dedicated smoke gate |
|
|
11
|
-
| 2.6.10 | Rails 5.2 | Best effort | Core CI and feature-detection contract; dedicated app gate incomplete |
|
|
12
|
-
| 2.7 and newer | None in 0.x | Unsupported | Belongs to transitional or modern lines |
|
|
13
|
-
|
|
14
|
-
| Ruby | Sidekiq integration | Status | Evidence |
|
|
15
|
-
|---|---|---|---|
|
|
16
|
-
| 2.2.10 | Sidekiq 4.2.10 | Best effort | Unit/integration contracts and dedicated real-gem Docker job |
|
|
17
|
-
| 2.5.9 | Sidekiq 5.2.10 | Best effort | Unit/integration contracts and dedicated real-gem Docker job |
|
|
5
|
+
## Core and Rack
|
|
18
6
|
|
|
19
|
-
|
|
7
|
+
| Ruby | Status | Evidence |
|
|
8
|
+
|---|---|---|
|
|
9
|
+
| 2.2.10 | Supported | Full unit, integration, contract, Rack, concurrency, fork, transport, privacy, and lint gate |
|
|
10
|
+
| 2.3.8 | Supported | Same dedicated Docker gate |
|
|
11
|
+
| 2.4.10 | Supported | Same dedicated Docker gate |
|
|
12
|
+
| 2.5.9 | Supported | Same dedicated Docker gate |
|
|
13
|
+
| 2.6.10 | Supported | Same dedicated Docker gate |
|
|
14
|
+
| 2.7 and newer | Unsupported in 1.x legacy | Belongs to the transitional or modern lines |
|
|
20
15
|
|
|
21
|
-
|
|
16
|
+
## Rails
|
|
22
17
|
|
|
23
|
-
|
|
18
|
+
| Ruby | Rails | Status | Evidence |
|
|
19
|
+
|---|---|---|---|
|
|
20
|
+
| 2.2.10 | 4.2 | Supported | Real application boot, successful/error request, SQL, view, cache, Active Job, mailer, fake endpoint, flush, and shutdown |
|
|
21
|
+
| 2.3.8 | 4.2 | Supported | Same dedicated application gate |
|
|
22
|
+
| 2.5.9 | 5.2 | Supported | Same dedicated application gate |
|
|
23
|
+
| 2.6.10 | 5.2 | Supported | Same dedicated application gate |
|
|
24
|
+
| Other Ruby/Rails pairs | — | Unsupported | No complete release gate; feature detection alone is not a support claim |
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
## Sidekiq
|
|
27
|
+
|
|
28
|
+
| Ruby | Sidekiq | Status | Evidence |
|
|
29
|
+
|---|---|---|---|
|
|
30
|
+
| 2.2.10 | 4.2.10 | Supported | Real-gem client/server middleware smoke with context, success/failure, and deduplication |
|
|
31
|
+
| 2.5.9 | 5.2.10 | Supported | Same dedicated application gate |
|
|
32
|
+
| Other Ruby/Sidekiq pairs | — | Unsupported | No complete release gate |
|
|
26
33
|
|
|
27
|
-
|
|
34
|
+
Active Job uses the public `serialize`, `deserialize`, and `perform_now` extension points with a bounded namespaced field. Support follows the validated Rails pairs above. Adapters that bypass these hooks require their own evidence.
|
|
28
35
|
|
|
29
|
-
|
|
36
|
+
The release workflow repeats every supported pair before publishing. Historical 1.0 evidence remains in [Version 1.0 readiness](release-1.0-readiness.md); the 1.1 candidate is recorded in [Version 1.1 readiness](release-1.1-readiness.md).
|
|
30
37
|
|
|
31
38
|
Status meanings:
|
|
32
39
|
|
|
33
|
-
- Supported:
|
|
34
|
-
- Best effort: intended to work
|
|
40
|
+
- Supported: every mandatory compatibility gate for the exact pair passes.
|
|
41
|
+
- Best effort: intended to work but missing a complete gate; no 1.1 pair is advertised this way.
|
|
35
42
|
- Deprecated: still tested while removal is planned.
|
|
36
|
-
- Unsupported: outside
|
|
43
|
+
- Unsupported: outside the tested 1.1 contract.
|
data/docs/configuration.md
CHANGED
|
@@ -63,6 +63,16 @@
|
|
|
63
63
|
| `apm_long_transaction_threshold_ms` | Optional | `1000.0` | Transaction-labelled SQL duration that produces a signal |
|
|
64
64
|
| `apm_n_plus_one_threshold` | Optional | `5` | Repeated fingerprint count producing one possible-N+1 signal; minimum 2 |
|
|
65
65
|
| `apm_histogram_buckets` | Optional | Fixed millisecond boundaries | Increasing positive duration boundaries; at most 19 plus `+Inf` |
|
|
66
|
+
| `apm_trace_ttl_seconds` | Optional | `60.0` | Maximum idle time retained for an incomplete trace or transaction tracker |
|
|
67
|
+
| `apm_query_analysis_enabled` | Optional | `true` | Analyzes bounded normalized SELECT shapes and emits informational/index-candidate diagnostics |
|
|
68
|
+
| `apm_query_analysis_max_queries` | Optional | `100` | Maximum normalized fingerprints analyzed and cached per subscriber; range 1–500 |
|
|
69
|
+
| `apm_query_inspection_enabled` | Optional | `false` | Opts in to read-only comparison with ActiveRecord index metadata |
|
|
70
|
+
| `apm_query_statistics_enabled` | Optional | `false` | Adds adapter-specific estimated table-row statistics; requires query inspection |
|
|
71
|
+
| `apm_query_plan_enabled` | Optional | `false` | Adds allowlisted `EXPLAIN` evidence for eligible SELECTs; never uses `ANALYZE` |
|
|
72
|
+
| `apm_query_inspection_min_duration_ms` | Optional | `500.0` | Minimum observed query duration before an opt-in database inspection |
|
|
73
|
+
| `apm_query_inspection_max_queries` | Optional | `20` | Maximum unique fingerprints inspected per subscriber; range 1–100 |
|
|
74
|
+
| `apm_transaction_tracking_enabled` | Optional | `true` | Measures bounded outer transaction elapsed time by notification connection |
|
|
75
|
+
| `apm_transaction_max_connections` | Optional | `100` | Maximum concurrently tracked transaction connections; range 1–500 |
|
|
66
76
|
| `external_http_enabled` | Optional | `false` | Allows explicit per-instance outbound `Net::HTTP` instrumentation |
|
|
67
77
|
| `external_http_trace_headers` | Optional | `true` | Propagates Chronos trace/request headers on instrumented requests |
|
|
68
78
|
| `cache_key_mode` | Optional | `:none` | `:none` omits keys; `:sha256` emits a project-scoped key hash |
|
|
@@ -102,6 +112,17 @@ Chronos.configure do |config|
|
|
|
102
112
|
config.apm_slow_query_threshold_ms = 500.0
|
|
103
113
|
config.apm_long_transaction_threshold_ms = 1000.0
|
|
104
114
|
config.apm_n_plus_one_threshold = 5
|
|
115
|
+
config.apm_trace_ttl_seconds = 60.0
|
|
116
|
+
config.apm_query_analysis_enabled = true
|
|
117
|
+
config.apm_query_analysis_max_queries = 100
|
|
118
|
+
# Database access is explicit because each inspected fingerprint adds read-only work.
|
|
119
|
+
config.apm_query_inspection_enabled = false
|
|
120
|
+
config.apm_query_statistics_enabled = false
|
|
121
|
+
config.apm_query_plan_enabled = false
|
|
122
|
+
config.apm_query_inspection_min_duration_ms = 500.0
|
|
123
|
+
config.apm_query_inspection_max_queries = 20
|
|
124
|
+
config.apm_transaction_tracking_enabled = true
|
|
125
|
+
config.apm_transaction_max_connections = 100
|
|
105
126
|
config.external_http_enabled = false
|
|
106
127
|
config.external_http_trace_headers = true
|
|
107
128
|
config.cache_key_mode = :none
|
data/docs/data-collected.md
CHANGED
|
@@ -33,13 +33,19 @@ Version 0.9 emits exceptions, cache telemetry, dependency/deploy events, and agg
|
|
|
33
33
|
| Sidekiq arguments | Collected, sanitized, and bounded | First 20 job arguments; collections/depth/strings limited |
|
|
34
34
|
| Sidekiq tags | Collected and bounded | Job payload or public worker options |
|
|
35
35
|
| Sidekiq trace/request IDs | Propagated when present; trace generated otherwise | Chronos job-envelope metadata |
|
|
36
|
-
| APM counts, error counts/rates, duration total/min/max/average | Aggregated by default | Request, query, and job observations |
|
|
37
|
-
| Fixed duration histogram
|
|
36
|
+
| APM counts, error counts/rates, duration total/min/max/average and approximate p50/p95/p99 | Aggregated by default | Request, query, and job observations plus fixed histogram |
|
|
37
|
+
| Fixed duration histogram, status counts, severity counts and bounded diagnostics | Aggregated by default | Local bounded counters and classifiers |
|
|
38
38
|
| Component breakdown | database/view/external_http/cache/queue/application when observable | Trace-local bounded totals |
|
|
39
39
|
| Normalized SQL and SHA-256 fingerprint | Collected without comments, literals, or binds | `sql.active_record` payload |
|
|
40
40
|
| SQL adapter, operation, inferred table, AR name, cache flag, role/shard | Collected when exposed | Public notification payload and connection feature detection |
|
|
41
41
|
| Slow SQL source frame | Collected only for threshold-selected slow queries | Bounded application call frame |
|
|
42
42
|
| APM diagnostic signals | Heuristic counters | Local threshold and repetition detection |
|
|
43
|
+
| SELECT tables and equality/range/join/order columns; index candidates | Collected by default from normalized SQL; bounded | Local static query analyzer |
|
|
44
|
+
| Existing index names/columns/uniqueness | Disabled by default; read-only opt-in | Public ActiveRecord schema metadata |
|
|
45
|
+
| Estimated table rows | Disabled by default; read-only opt-in | PostgreSQL `pg_class` or MySQL `information_schema` |
|
|
46
|
+
| Allowlisted plan node type/table/index/estimated rows/cost | Disabled by default; `EXPLAIN` without `ANALYZE` | Local database planner |
|
|
47
|
+
| Complete outer transaction approximate duration | Collected by default with bounded state | BEGIN/COMMIT/ROLLBACK notifications keyed by local connection identity |
|
|
48
|
+
| Trace tracking loss/expiration counters | Aggregated by default | Local bounded tracker lifecycle |
|
|
43
49
|
| External HTTP host, method, status, duration, timeout, connection-error flag, error class | Disabled by default; per-instance opt-in | Instrumented `Net::HTTP` object |
|
|
44
50
|
| Chronos trace/request headers | Propagated when available | Current execution context |
|
|
45
51
|
| Cache operation, backend, namespace, hit/miss, duration | Collected; key/value omitted | ActiveSupport cache notifications |
|
|
@@ -50,7 +56,7 @@ Version 0.9 emits exceptions, cache telemetry, dependency/deploy events, and agg
|
|
|
50
56
|
| Deploy environment, revision, version, repository, actor, deploy ID, service, region, instance | Explicit synchronous deploy API | Application/deployment integration arguments |
|
|
51
57
|
| Integration verification ID, fixed test marker, synthetic exception class/message, and receipt correlation | Only when `Chronos.verify_integration` or its Rake task is invoked | Locally generated bounded values |
|
|
52
58
|
|
|
53
|
-
The gem never
|
|
59
|
+
The gem never transmits request bodies, response bodies, raw query strings, cookies, HTTP authorization headers, environment variables in bulk, Git state, source code, raw SQL, SQL bind values, database rows, plan predicates, raw cache keys/values, mail bodies/recipients, Active Job arguments, gem paths, or lockfile contents. Opt-in plan inspection temporarily supplies the already observed local SELECT to `EXPLAIN` without `ANALYZE` and discards it. Active Job IDs, Sidekiq JIDs/arguments, loaded gem names/versions, and deploy fields are documented integration data.
|
|
54
60
|
|
|
55
61
|
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.
|
|
56
62
|
|
data/docs/deprecation-policy.md
CHANGED
|
@@ -4,4 +4,4 @@ After `1.0.0`, a public API scheduled for removal remains available for at least
|
|
|
4
4
|
|
|
5
5
|
Warnings are emitted at most once per process through the configured safe logger and must not include application payloads. Security fixes, behavior that can expose secrets, and upstream runtime incompatibilities may require faster action; the security advisory and changelog must explain the exception. Ruby/Rails support changes are recorded in `docs/compatibility.md` before removal.
|
|
6
6
|
|
|
7
|
-
Prereleases may revise APIs without the full stable window, but every incompatible revision must remain explicit. Version `0.
|
|
7
|
+
Prereleases may revise APIs without the full stable window, but every incompatible revision must remain explicit. Version `1.0.0` starts the stable deprecation window and introduces no removal.
|
data/docs/examples/plain-ruby.md
CHANGED
|
@@ -29,6 +29,12 @@ For network-free per-instance outbound HTTP instrumentation, run:
|
|
|
29
29
|
bundle _1.17.3_ exec ruby examples/plain-ruby/external_http.rb
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
+
For a network-free normalized-query/index diagnostic example, run:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
bundle _1.17.3_ exec ruby examples/plain-ruby/query_analysis.rb
|
|
36
|
+
```
|
|
37
|
+
|
|
32
38
|
For a network-free deploy event with complete release correlation, run:
|
|
33
39
|
|
|
34
40
|
```bash
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Migration from Airbrake
|
|
2
2
|
|
|
3
|
-
Version `0.
|
|
3
|
+
Version `1.0.0` provides a staged migration path. Run both agents only long enough to compare delivery, then remove Airbrake to avoid duplicate reports and overhead.
|
|
4
4
|
|
|
5
5
|
| Airbrake concept | Chronos equivalent |
|
|
6
6
|
|---|---|
|
|
@@ -4,13 +4,13 @@ Version `0.8.0.pre.1` aggregates request, SQL, job, and explicitly instrumented
|
|
|
4
4
|
|
|
5
5
|
## Request metrics
|
|
6
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.
|
|
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, approximate p50/p95/p99 upper bounds, severity counts, bounded diagnostics, and component breakdown. The SaaS may calculate more precise percentiles from merged histograms; the agent never retains raw duration arrays.
|
|
8
8
|
|
|
9
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
10
|
|
|
11
11
|
## SQL metrics and signals
|
|
12
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.
|
|
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. `SqlQueryAnalyzer` extracts bounded SELECT access columns. The optional `ActiveRecordQueryInspector` compares existing indexes and adds allowlisted statistics/plans without retaining raw SQL. 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
14
|
|
|
15
15
|
Local signals are intentionally heuristic:
|
|
16
16
|
|
|
@@ -18,7 +18,8 @@ Local signals are intentionally heuristic:
|
|
|
18
18
|
- `repeated_query` after the same fingerprint appears again in one trace;
|
|
19
19
|
- `possible_n_plus_one` once when the configured repetition threshold is reached;
|
|
20
20
|
- `long_transaction` for transaction-labelled SQL over its threshold;
|
|
21
|
-
- `connection_error
|
|
21
|
+
- `connection_error`, query/pool/lock timeout, constraint violation, and `deadlock` from bounded exception class names;
|
|
22
|
+
- index candidate/coverage and sequential-scan evidence from bounded query analysis.
|
|
22
23
|
|
|
23
24
|
The SaaS must confirm and correlate these signals. They are not proof of an N+1, deadlock, or application defect.
|
|
24
25
|
|
|
@@ -29,9 +30,11 @@ The SaaS must confirm and correlate these signals. They are not proof of an N+1,
|
|
|
29
30
|
- at most `apm_max_queries_per_request` fingerprints per trace;
|
|
30
31
|
- at most 19 configured histogram boundaries plus `+Inf`;
|
|
31
32
|
- at most `apm_batch_size` groups per payload, with a hard maximum of 50;
|
|
32
|
-
- trackers are removed when their request completes
|
|
33
|
+
- trackers are removed when their request completes or their idle TTL expires; aggregate drain preserves active trackers;
|
|
34
|
+
- at most 20 diagnostics and one representative bounded query analysis per metric group;
|
|
35
|
+
- at most `apm_query_inspection_max_queries` database inspections per Rails subscriber.
|
|
33
36
|
|
|
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.
|
|
37
|
+
New groups beyond capacity are dropped and counted in `dropped_groups`. Tracking loss is reported through `dropped_trace_trackers`, `expired_trace_trackers`, and `dropped_query_fingerprints`. Existing groups continue accumulating. The state is process-local and is lost on restart.
|
|
35
38
|
|
|
36
39
|
## Breakdown
|
|
37
40
|
|
|
@@ -51,6 +54,16 @@ Chronos.configure do |config|
|
|
|
51
54
|
config.apm_long_transaction_threshold_ms = 1000.0
|
|
52
55
|
config.apm_n_plus_one_threshold = 5
|
|
53
56
|
config.apm_histogram_buckets = [5.0, 10.0, 25.0, 50.0, 100.0, 250.0, 500.0, 1000.0]
|
|
57
|
+
config.apm_trace_ttl_seconds = 60.0
|
|
58
|
+
config.apm_query_analysis_enabled = true
|
|
59
|
+
config.apm_query_analysis_max_queries = 100
|
|
60
|
+
config.apm_query_inspection_enabled = false
|
|
61
|
+
config.apm_query_statistics_enabled = false
|
|
62
|
+
config.apm_query_plan_enabled = false
|
|
63
|
+
config.apm_query_inspection_min_duration_ms = 500.0
|
|
64
|
+
config.apm_query_inspection_max_queries = 20
|
|
65
|
+
config.apm_transaction_tracking_enabled = true
|
|
66
|
+
config.apm_transaction_max_connections = 100
|
|
54
67
|
end
|
|
55
68
|
```
|
|
56
69
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Breadcrumbs
|
|
2
|
+
|
|
3
|
+
## Problema e limite
|
|
4
|
+
|
|
5
|
+
Breadcrumbs preservam uma trilha curta do fluxo que antecedeu uma falha. Não são logs, tracing completo ou armazenamento de payloads brutos.
|
|
6
|
+
|
|
7
|
+
## Fluxo e classes
|
|
8
|
+
|
|
9
|
+
`Chronos.add_breadcrumb` normaliza a categoria e os metadados em `Chronos::Core::Breadcrumb`. `BreadcrumbBuffer` mantém um anel de capacidade fixa no context store. O `NoticeBuilder` copia a fotografia atual; sanitizer e serializer aplicam novamente limites antes da entrega.
|
|
10
|
+
|
|
11
|
+
## Extensão, riscos e exemplo
|
|
12
|
+
|
|
13
|
+
Integrações podem registrar apenas categorias conhecidas e metadados de baixa cardinalidade. Mensagens e metadados continuam sendo dados da aplicação e podem conter informação pessoal se o chamador ignorar minimização.
|
|
14
|
+
|
|
15
|
+
```ruby
|
|
16
|
+
Chronos.add_breadcrumb(
|
|
17
|
+
:category => "custom",
|
|
18
|
+
:message => "invoice queued",
|
|
19
|
+
:metadata => {"provider" => "example"}
|
|
20
|
+
)
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Os limites e a herança por captura são testados em `spec/unit/core/breadcrumb_spec.rb`, `spec/unit/agent_spec.rb` e nos specs de Rack.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Contexto de execução
|
|
2
|
+
|
|
3
|
+
## Problema e limite
|
|
4
|
+
|
|
5
|
+
O contexto relaciona uma exceção ou métrica ao request/job atual sem criar dependência do núcleo com Rack, Rails ou Sidekiq. Ele guarda somente valores delimitados e não é um repositório de estado da aplicação.
|
|
6
|
+
|
|
7
|
+
## Fluxo e classes
|
|
8
|
+
|
|
9
|
+
`Chronos::Ports::ContextStore` define `get`, `set`, `clear` e `with_context`. Na linha legado, `Chronos::Adapters::ThreadLocalContextStore` isola o valor por thread. A fachada combina o contexto explícito com o escopo atual; o serializer sanitiza e limita tudo antes da fila. Rack limpa o escopo em `ensure`, enquanto Sidekiq e Active Job propagam apenas `trace_id` e `request_id`.
|
|
10
|
+
|
|
11
|
+
## Extensão, riscos e exemplo
|
|
12
|
+
|
|
13
|
+
Um adaptador alternativo pode ser configurado quando implementar a porta completa. Ele precisa restaurar escopos aninhados e garantir limpeza após exceções. Thread local não acompanha automaticamente fibers ou threads criadas pela aplicação; nesses casos, propague somente os identificadores permitidos.
|
|
14
|
+
|
|
15
|
+
```ruby
|
|
16
|
+
Chronos.with_context("trace_id" => "trace-42", "request_id" => "request-7") do
|
|
17
|
+
Chronos.notify(RuntimeError.new("failure"))
|
|
18
|
+
end
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Os contratos estão em `spec/unit/ports/context_store_spec.rb`, `spec/unit/adapters/thread_local_context_store_spec.rb` e `spec/integration/rack_middleware_concurrency_spec.rb`.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Deploys
|
|
2
|
+
|
|
3
|
+
## Problema e limite
|
|
4
|
+
|
|
5
|
+
Deploys criam o marco temporal usado para comparar erros e desempenho antes/depois de uma release. A gem informa o evento; reconciliação e análise pertencem ao SaaS.
|
|
6
|
+
|
|
7
|
+
## Fluxo e classes
|
|
8
|
+
|
|
9
|
+
`Chronos.notify_deploy` passa atributos explícitos a `Core::DeployNormalizer`, sanitiza o evento e usa entrega síncrona com idempotência. `CorrelationContext` copia release, revision, deploy ID, ambiente, serviço, região e instância para todos os envelopes. Uma entrega bem-sucedida libera um novo snapshot de dependências.
|
|
10
|
+
|
|
11
|
+
## Extensão, riscos e exemplo
|
|
12
|
+
|
|
13
|
+
Capistrano possui hook opcional; Kamal e GitHub Actions usam comandos documentados. A gem não lê Git nem variáveis automaticamente. O retorno `false` deve ser tratado conforme a política de deploy da aplicação.
|
|
14
|
+
|
|
15
|
+
```ruby
|
|
16
|
+
Chronos.notify_deploy(
|
|
17
|
+
:environment => "production",
|
|
18
|
+
:revision => ENV["GIT_SHA"],
|
|
19
|
+
:version => ENV["APP_VERSION"]
|
|
20
|
+
)
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Veja `spec/unit/core/deploy_normalizer_spec.rb`, `spec/unit/integrations/capistrano_spec.rb` e `spec/integration/deploy_delivery_spec.rb`.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Monitoramento de jobs
|
|
2
|
+
|
|
3
|
+
## Problema e limite
|
|
4
|
+
|
|
5
|
+
Jobs precisam manter correlação entre enqueue e execução e registrar duração/falha sem abrir threads ou conexões por job. A versão 1.0 cobre Sidekiq 4/5 e Active Job disponível em Rails 4.2/5.2; Resque e Delayed Job permanecem fora do escopo estável.
|
|
6
|
+
|
|
7
|
+
## Fluxo e classes
|
|
8
|
+
|
|
9
|
+
O middleware Sidekiq injeta um envelope Chronos separado dos argumentos públicos. O servidor restaura contexto, mede fila/execução e deduplica exceções aninhadas. A integração Active Job usa os hooks públicos de serialização e `perform_now`. As observações seguem para `ApmAggregator` e as exceções para o notice pipeline.
|
|
10
|
+
|
|
11
|
+
## Extensão, riscos e exemplo
|
|
12
|
+
|
|
13
|
+
Adapters que substituem hooks públicos exigem testes próprios. Argumentos Sidekiq são limitados e sanitizados, mas a aplicação deve evitar segredos e dados pessoais desnecessários.
|
|
14
|
+
|
|
15
|
+
```ruby
|
|
16
|
+
require "chronos/sidekiq"
|
|
17
|
+
Sidekiq.configure_server do |config|
|
|
18
|
+
config.server_middleware { |chain| chain.add Chronos::Integrations::Sidekiq::ServerMiddleware }
|
|
19
|
+
end
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Veja `spec/unit/integrations/sidekiq_spec.rb`, `spec/unit/integrations/active_job_spec.rb` e `spec/integration/sidekiq_delivery_spec.rb`.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Monitoramento de requests
|
|
2
|
+
|
|
3
|
+
## Problema e limite
|
|
4
|
+
|
|
5
|
+
Requests Rack/Rails alimentam métricas de duração, status e breakdown com dimensões limitadas. O módulo não lê bodies, cookies, autorização ou query string bruta.
|
|
6
|
+
|
|
7
|
+
## Fluxo e classes
|
|
8
|
+
|
|
9
|
+
O middleware Rack cria contexto isolado e mede o request. Subscribers Rails enriquecem controller/action e evitam duplicação. `CaptureTelemetry` envia a observação a `ApmAggregator`; por padrão ela integra um `metric_batch`, e com APM desativado vira evento individual sanitizado.
|
|
10
|
+
|
|
11
|
+
## Extensão, riscos e exemplo
|
|
12
|
+
|
|
13
|
+
Rotas devem ser normalizadas para evitar cardinalidade por ID. Aplicações Rack podem fornecer um normalizador por meio dos campos já aceitos, sem incluir parâmetros sensíveis.
|
|
14
|
+
|
|
15
|
+
```ruby
|
|
16
|
+
use Chronos::Integrations::Rack::Middleware,
|
|
17
|
+
:include_user_agent => false
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Veja `spec/integration/rack_middleware_spec.rb`, `spec/integration/rack_middleware_concurrency_spec.rb` e `spec/integration/apm_aggregation_delivery_spec.rb`.
|