chronos-ruby 1.0.0 → 1.2.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 +36 -0
- data/README.md +27 -13
- data/contracts/apm-batch-v1.schema.json +51 -1
- data/docs/adr/ADR-010-opentelemetry-interoperability.md +3 -3
- data/docs/adr/ADR-015-bounded-apm-aggregation.md +3 -3
- data/docs/adr/ADR-019-bounded-query-diagnostics.md +44 -0
- data/docs/architecture.md +5 -2
- data/docs/compatibility.md +12 -18
- data/docs/configuration.md +27 -2
- data/docs/data-collected.md +9 -3
- data/docs/examples/plain-ruby.md +6 -0
- data/docs/modules/apm-aggregation.md +18 -5
- data/docs/modules/context.md +1 -1
- data/docs/modules/external-http.md +3 -2
- data/docs/modules/sidekiq-legacy.md +1 -1
- data/docs/modules/sql-monitoring.md +60 -6
- data/docs/modules/telemetry-events.md +1 -1
- data/docs/performance.md +19 -3
- data/docs/privacy-lgpd.md +6 -3
- data/docs/protocol-v1.md +1 -1
- 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/adapters/fiber_local_context_store.rb +57 -0
- data/lib/chronos/agent.rb +19 -3
- data/lib/chronos/application/apm_aggregator.rb +179 -29
- data/lib/chronos/configuration/apm_validation.rb +53 -1
- data/lib/chronos/configuration/validation.rb +2 -2
- data/lib/chronos/configuration.rb +21 -2
- data/lib/chronos/core/metric_aggregate.rb +69 -7
- data/lib/chronos/core/sql_query_analyzer.rb +309 -0
- data/lib/chronos/core/trace_context.rb +38 -0
- data/lib/chronos/integrations/active_job.rb +2 -2
- data/lib/chronos/integrations/faraday.rb +76 -0
- data/lib/chronos/integrations/net_http.rb +5 -1
- data/lib/chronos/integrations/opentelemetry.rb +44 -0
- data/lib/chronos/integrations/rack/middleware.rb +8 -2
- data/lib/chronos/integrations/sidekiq.rb +1 -1
- data/lib/chronos/ports/query_inspector.rb +23 -0
- data/lib/chronos/rails/active_record_query_inspector.rb +235 -0
- data/lib/chronos/rails/error_reporter_subscriber.rb +39 -0
- data/lib/chronos/rails/installer.rb +13 -0
- data/lib/chronos/rails/notifications_subscriber.rb +175 -2
- data/lib/chronos/rails.rb +2 -0
- data/lib/chronos/version.rb +2 -2
- data/lib/chronos.rb +6 -0
- metadata +46 -38
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c13c2858edcb41d4b2a0bfc83049349ee13a5a9ecee873798750b4bf9f1da48c
|
|
4
|
+
data.tar.gz: a21babcc28ce763e7d867f35064735d661214724c1ed9d256e8d174a1a04c5dc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 81ab0672785236e1ffaeecf0fbb5ae3187f319be349a06f724eee50dd0d20963afb74a84485267e8ea5e3a7dd37dacef15ab456783fee622bef901110b98344a
|
|
7
|
+
data.tar.gz: 835ee551ddcec646a44376dcdfc09748e12c0fa360fee62365455e6776503a0597baed504a33276059853e652f5a90458ad7ae43bb582f7647303af9940a5d1f
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,42 @@ All notable changes are documented here. The project follows Semantic Versioning
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [1.2.0.pre.1] - 2026-08-11
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- fiber-aware execution context with a thread-local fallback;
|
|
12
|
+
- Sidekiq 7 and Rails 7 error reporter integration using public extension APIs;
|
|
13
|
+
- Action Cable notification spans and a dependency-free Faraday middleware;
|
|
14
|
+
- optional W3C `traceparent` propagation and an OpenTelemetry bridge that consumes the active span without installing an SDK or exporter.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- the transitional runtime range is Ruby 2.7 through 3.4 and the default context strategy is `:fiber_local`;
|
|
19
|
+
- Active Job and Sidekiq envelopes may propagate allowlisted span ID and trace flags in addition to trace/request IDs.
|
|
20
|
+
|
|
21
|
+
### Security
|
|
22
|
+
|
|
23
|
+
- W3C identifiers are syntax-validated, all-zero IDs are rejected, and Rails error reporter context is reduced to bounded allowlisted metadata.
|
|
24
|
+
|
|
25
|
+
## [1.1.0] - 2026-08-05
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
|
|
29
|
+
- bounded normalized SELECT analysis with access columns, index candidates, existing-index comparison, optional table statistics, and allowlisted non-executing query plans;
|
|
30
|
+
- structured query diagnostics and severity counts for errors, warnings, information, and suggestions, including actionable N+1 and index guidance;
|
|
31
|
+
- approximate p50/p95/p99 metrics, complete outer-transaction timing, expanded adapter error families, and trace/fingerprint loss counters;
|
|
32
|
+
- explicit low-risk defaults and bounded opt-in configuration for database index/statistics/plan inspection.
|
|
33
|
+
|
|
34
|
+
### Changed
|
|
35
|
+
|
|
36
|
+
- aggregate drains preserve active trace trackers until request completion or idle TTL instead of discarding incomplete correlation;
|
|
37
|
+
- possible N+1 now requires a non-cached SELECT, and query analysis sent to consumers prefers inspected evidence over an earlier static-only observation.
|
|
38
|
+
|
|
39
|
+
### Security
|
|
40
|
+
|
|
41
|
+
- query inspection never uses `EXPLAIN ANALYZE`, never executes DDL, omits raw SQL/binds/predicates/messages, and retains only bounded schema and planner fields.
|
|
42
|
+
|
|
7
43
|
## [1.0.0] - 2026-07-29
|
|
8
44
|
|
|
9
45
|
### Added
|
data/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Chronos Ruby
|
|
2
2
|
|
|
3
|
-
Chronos Ruby 1.
|
|
3
|
+
Chronos Ruby 1.1.0 é o agente independente de framework para enviar exceções e telemetria limitada de aplicações Ruby ao Chronos. Esta é a linha estável legado, compatível com o protocolo v1 e voltada a Ruby 2.2.10–2.6.
|
|
4
4
|
|
|
5
5
|
## O que a gem coleta
|
|
6
6
|
|
|
7
|
-
A versão 1.
|
|
7
|
+
A versão 1.1 pode coletar:
|
|
8
8
|
|
|
9
9
|
- classe, mensagem, backtrace estruturado e causas encadeadas da exceção;
|
|
10
10
|
- timestamp, severidade, tags e fingerprint opcional;
|
|
@@ -20,11 +20,11 @@ Veja a tabela completa em [Dados coletados](docs/data-collected.md).
|
|
|
20
20
|
|
|
21
21
|
## O que não é coletado por padrão
|
|
22
22
|
|
|
23
|
-
A gem não varre variáveis de ambiente, sistema de arquivos ou lockfiles e não
|
|
23
|
+
A gem não varre variáveis de ambiente, sistema de arquivos ou lockfiles e não coleta bodies HTTP, cookies, headers de autorização, conteúdo de e-mail, SQL bruto, binds, valores de cache ou código-fonte. A inspeção de plano, desativada por padrão, usa o SQL original somente na conexão local para `EXPLAIN` sem `ANALYZE` e o descarta. O inventário de dependências contém somente nomes e versões já carregados, uma vez por agente. A aplicação continua responsável por minimização e base legal dos dados enviados.
|
|
24
24
|
|
|
25
25
|
## Versões Ruby e Rails suportadas
|
|
26
26
|
|
|
27
|
-
A versão 1.0.
|
|
27
|
+
A versão candidata 1.2.0.pre.1 inicia a linha transitional para Ruby 2.7–3.4, Rails 7.x e Sidekiq 7. Ela adiciona contexto por Fiber, Rails Error Reporter, Action Cable, Faraday, Trace Context W3C opcional e coexistência com um SDK OpenTelemetry já configurado. Use-a explicitamente em staging enquanto a matriz transitional é validada; as linhas legadas permanecem disponíveis em releases anteriores.
|
|
28
28
|
|
|
29
29
|
Rubies e frameworks antigos estão fora do suporte de segurança de seus mantenedores. A Chronos oferece compatibilidade técnica, não manutenção de segurança do runtime. Veja [Compatibilidade](docs/compatibility.md).
|
|
30
30
|
|
|
@@ -33,7 +33,7 @@ Rubies e frameworks antigos estão fora do suporte de segurança de seus mantene
|
|
|
33
33
|
Obrigatório: adicione a versão estável ao `Gemfile`.
|
|
34
34
|
|
|
35
35
|
```ruby
|
|
36
|
-
gem "chronos-ruby", "~> 1.
|
|
36
|
+
gem "chronos-ruby", "~> 1.1.0"
|
|
37
37
|
```
|
|
38
38
|
|
|
39
39
|
Em runtimes antigos, use Bundler compatível:
|
|
@@ -46,7 +46,7 @@ bundle _1.17.3_ install
|
|
|
46
46
|
Sem Bundler:
|
|
47
47
|
|
|
48
48
|
```bash
|
|
49
|
-
gem install chronos-ruby -v 1.
|
|
49
|
+
gem install chronos-ruby -v 1.1.0
|
|
50
50
|
```
|
|
51
51
|
|
|
52
52
|
## Instalação em Rails
|
|
@@ -54,7 +54,7 @@ gem install chronos-ruby -v 1.0.0
|
|
|
54
54
|
Obrigatório: carregue a integração Rails explicitamente para manter Rails/ActiveSupport fora de aplicações Ruby puras.
|
|
55
55
|
|
|
56
56
|
```ruby
|
|
57
|
-
gem "chronos-ruby", "~> 1.
|
|
57
|
+
gem "chronos-ruby", "~> 1.1.0", :require => "chronos/rails"
|
|
58
58
|
```
|
|
59
59
|
|
|
60
60
|
Gere o initializer:
|
|
@@ -174,7 +174,7 @@ A regra recebe um notice normalizado e imutável, e somente `true` descarta. Fal
|
|
|
174
174
|
|
|
175
175
|
## Monitoramento de performance
|
|
176
176
|
|
|
177
|
-
A Versão 0.7 introduziu agregação local de requests, queries e jobs em `metric_batch`; a Versão 0.8 adicionou HTTP externo. Grupos possuem contagem, erro, duração, histograma, status e breakdown limitados.
|
|
177
|
+
A Versão 0.7 introduziu agregação local de requests, queries e jobs em `metric_batch`; a Versão 0.8 adicionou HTTP externo. Grupos possuem contagem, erro, duração, histograma, percentis aproximados, severidades, diagnósticos, status e breakdown limitados.
|
|
178
178
|
|
|
179
179
|
```ruby
|
|
180
180
|
Chronos.configure do |config|
|
|
@@ -185,21 +185,35 @@ Chronos.configure do |config|
|
|
|
185
185
|
config.apm_max_queries_per_request = 100
|
|
186
186
|
config.apm_slow_query_threshold_ms = 500.0
|
|
187
187
|
config.apm_n_plus_one_threshold = 5
|
|
188
|
+
config.apm_trace_ttl_seconds = 60.0
|
|
189
|
+
config.apm_query_analysis_enabled = true
|
|
190
|
+
config.apm_query_analysis_max_queries = 100
|
|
191
|
+
|
|
192
|
+
# Opt-in: cada fingerprint elegível pode consultar catálogo/estatística/plano.
|
|
193
|
+
config.apm_query_inspection_enabled = false
|
|
194
|
+
config.apm_query_statistics_enabled = false
|
|
195
|
+
config.apm_query_plan_enabled = false
|
|
196
|
+
config.apm_query_inspection_min_duration_ms = 500.0
|
|
197
|
+
config.apm_query_inspection_max_queries = 20
|
|
198
|
+
config.apm_transaction_tracking_enabled = true
|
|
199
|
+
config.apm_transaction_max_connections = 100
|
|
188
200
|
end
|
|
189
201
|
```
|
|
190
202
|
|
|
191
|
-
SQL bruto e binds não são lidos
|
|
203
|
+
Por padrão, SQL bruto e binds não são lidos pelo pipeline de análise. A inspeção opt-in usa o SQL original apenas localmente para solicitar `EXPLAIN` sem `ANALYZE`; nunca o inclui no evento. A análise estática produz candidatos, não ordens de criação de índice. Erros usam severidade `error`; lentidão e risco usam `warning`; padrões observados usam `info`; correções propostas usam `suggestion`. Veja [APM](docs/modules/apm-aggregation.md), [Requests](docs/modules/request-monitoring.md) e [SQL](docs/modules/sql-monitoring.md).
|
|
192
204
|
|
|
193
205
|
## Sidekiq e Active Job
|
|
194
206
|
|
|
195
|
-
A
|
|
207
|
+
A integração mantém o require explícito e suporta a API pública de middleware do Sidekiq 7:
|
|
208
|
+
|
|
209
|
+
O suporte histórico começou em `0.6.0.pre.1`; aplicações em Sidekiq 4/5 devem permanecer numa release legada compatível.
|
|
196
210
|
|
|
197
211
|
```ruby
|
|
198
212
|
gem "sidekiq", "~> 5.0"
|
|
199
|
-
gem "chronos-ruby", "~> 1.
|
|
213
|
+
gem "chronos-ruby", "~> 1.1.0", :require => "chronos/sidekiq"
|
|
200
214
|
```
|
|
201
215
|
|
|
202
|
-
O envelope de contexto não altera argumentos públicos e contém somente IDs limitados de trace/request. Active Job usa um campo serializado com namespace (`chronos_context`) e hooks públicos. Erros aninhados são deduplicados e reerguidos. Veja [Sidekiq legado](docs/modules/sidekiq-legacy.md), [Active Job](docs/modules/active-job.md) e [Jobs](docs/modules/job-monitoring.md).
|
|
216
|
+
O envelope de contexto não altera argumentos públicos e contém somente IDs limitados de trace/span/request e flags. Active Job usa um campo serializado com namespace (`chronos_context`) e hooks públicos. Erros aninhados são deduplicados e reerguidos. Veja [Sidekiq legado](docs/modules/sidekiq-legacy.md), [Active Job](docs/modules/active-job.md) e [Jobs](docs/modules/job-monitoring.md).
|
|
203
217
|
|
|
204
218
|
## Deploy tracking
|
|
205
219
|
|
|
@@ -307,7 +321,7 @@ Execute suíte e lint no runtime atual:
|
|
|
307
321
|
bundle _1.17.3_ exec rake
|
|
308
322
|
```
|
|
309
323
|
|
|
310
|
-
A matriz CI cobre
|
|
324
|
+
A matriz CI cobre a linha transitional e os checks de pacote/documentação; workflows legados preservam evidência das releases anteriores.
|
|
311
325
|
|
|
312
326
|
## Contribuição
|
|
313
327
|
|
|
@@ -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
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Status
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Aceito para 1.2.
|
|
6
6
|
|
|
7
7
|
## Contexto
|
|
8
8
|
|
|
@@ -10,7 +10,7 @@ O Chronos precisa correlacionar trace/request sem duplicar SDKs ou impor depend
|
|
|
10
10
|
|
|
11
11
|
## Decisão
|
|
12
12
|
|
|
13
|
-
Manter IDs de correlação e portas independentes do fornecedor
|
|
13
|
+
Manter IDs de correlação e portas independentes do fornecedor. Na 1.2, a ponte opcional consulta somente o span atual de um SDK já carregado, traduz `trace_id`, `span_id` e flags, e nunca instala SDK, instrumentação ou exporter. IDs Chronos explícitos têm precedência; a presença de OTel deve ser usada pelas integrações para evitar spans paralelos equivalentes.
|
|
14
14
|
|
|
15
15
|
## Alternativas
|
|
16
16
|
|
|
@@ -22,4 +22,4 @@ O protocolo v1 permanece estável e aplicações legadas não recebem novas depe
|
|
|
22
22
|
|
|
23
23
|
## Consequências negativas
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
A ponte não exporta spans OTel completos nem controla exporters; consumidores que precisam desses dados continuam responsáveis pela configuração do SDK.
|
|
@@ -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.
|
|
@@ -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,43 +1,37 @@
|
|
|
1
1
|
# Compatibility
|
|
2
2
|
|
|
3
|
-
Chronos Ruby 1.0 is the
|
|
3
|
+
Chronos Ruby 1.2.0.pre.1 is the first candidate of the transitional line for Rails 7 and Sidekiq 7. Combinations remain `Best effort` until their dedicated CI and real-application gates pass. Technical compatibility does not make an end-of-life Ruby, Rails, Rack, or Sidekiq release secure. Versions 1.0 and 1.1 remain the frozen legacy line.
|
|
4
4
|
|
|
5
5
|
## Core and Rack
|
|
6
6
|
|
|
7
7
|
| Ruby | Status | Evidence |
|
|
8
8
|
|---|---|---|
|
|
9
|
-
| 2.2
|
|
10
|
-
|
|
|
11
|
-
| 2.
|
|
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 |
|
|
9
|
+
| 2.7–3.2 | Best effort | Transitional matrix introduced in this candidate; promotion requires green CI evidence |
|
|
10
|
+
| 3.3–3.4 | Best effort | Core checks run in modern CI; Rails 8-specific behavior belongs to 2.x |
|
|
11
|
+
| Earlier than 2.7 | Unsupported in 1.2 | Use an appropriate frozen legacy release |
|
|
15
12
|
|
|
16
13
|
## Rails
|
|
17
14
|
|
|
18
15
|
| Ruby | Rails | Status | Evidence |
|
|
19
16
|
|---|---|---|---|
|
|
20
|
-
| 2.2
|
|
21
|
-
|
|
|
22
|
-
|
|
|
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 |
|
|
17
|
+
| 2.7–3.2 | 7.0–7.1 | Best effort | Real Rails applications and the complete integration gate are pending |
|
|
18
|
+
| 3.1–3.4 | 7.2 | Best effort | Feature and package checks; use a validated application combination before production rollout |
|
|
19
|
+
| Rails 4–6 | — | Unsupported in 1.2 | Use a matching earlier Chronos release |
|
|
25
20
|
|
|
26
21
|
## Sidekiq
|
|
27
22
|
|
|
28
23
|
| Ruby | Sidekiq | Status | Evidence |
|
|
29
24
|
|---|---|---|---|
|
|
30
|
-
| 2.
|
|
31
|
-
|
|
|
32
|
-
| Other Ruby/Sidekiq pairs | — | Unsupported | No complete release gate |
|
|
25
|
+
| 2.7–3.4 | 7.x | Best effort | Real Sidekiq 7 smoke applications are pending |
|
|
26
|
+
| Sidekiq 4–6 | — | Unsupported in 1.2 | Use a matching earlier Chronos release |
|
|
33
27
|
|
|
34
28
|
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.
|
|
35
29
|
|
|
36
|
-
|
|
30
|
+
Historical evidence remains in [Version 1.0 readiness](release-1.0-readiness.md) and [Version 1.1 readiness](release-1.1-readiness.md).
|
|
37
31
|
|
|
38
32
|
Status meanings:
|
|
39
33
|
|
|
40
34
|
- Supported: every mandatory compatibility gate for the exact pair passes.
|
|
41
|
-
- Best effort: intended to work but missing a complete gate; no 1.
|
|
35
|
+
- Best effort: intended to work but missing a complete gate; no 1.1 pair is advertised this way.
|
|
42
36
|
- Deprecated: still tested while removal is planned.
|
|
43
|
-
- Unsupported: outside the tested 1.
|
|
37
|
+
- Unsupported: outside the tested 1.1 contract.
|
data/docs/configuration.md
CHANGED
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
| `sampling_rate` | Optional | `1.0` | Local upper bound for event sampling |
|
|
48
48
|
| `enabled_event_types` | Optional | exception, request, query, job, cache, external_http, dependencies, deploy, metric_batch | Local allowlist for supported event envelopes |
|
|
49
49
|
| `max_remote_send_interval` | Optional | `60.0` | Local upper bound for remotely requested send spacing |
|
|
50
|
-
| `context_store` | Optional | `:
|
|
50
|
+
| `context_store` | Optional | `:fiber_local` | `:fiber_local`, `:thread_local`, or an object implementing `get`, `set`, `clear`, and `with_context` |
|
|
51
51
|
| `breadcrumb_capacity` | Optional | `20` | Positive count of newest breadcrumbs retained per execution |
|
|
52
52
|
| `breadcrumb_max_bytes` | Optional | `2048` | Maximum bytes per normalized breadcrumb; minimum `128` |
|
|
53
53
|
| `rails_enabled` | Optional | `true` | Enables automatic Rails middleware and subscribers |
|
|
@@ -63,8 +63,20 @@
|
|
|
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 |
|
|
78
|
+
| `w3c_trace_context` | Optional | `false` | Injects a validated W3C `traceparent` header when trace and span IDs exist |
|
|
79
|
+
| `opentelemetry_bridge` | Optional | `true` | Consumes the current OpenTelemetry span when an SDK is already active; installs nothing |
|
|
68
80
|
| `cache_key_mode` | Optional | `:none` | `:none` omits keys; `:sha256` emits a project-scoped key hash |
|
|
69
81
|
| `dependency_reporting` | Optional | `true` | Emits one bounded dependency event per configured agent |
|
|
70
82
|
| `dependency_max_items` | Optional | `100` | Loaded gem entries retained in the inventory; range 1–200 |
|
|
@@ -90,7 +102,7 @@ Chronos.configure do |config|
|
|
|
90
102
|
config.max_retries = 3
|
|
91
103
|
config.backlog_size = 100
|
|
92
104
|
config.circuit_failure_threshold = 5
|
|
93
|
-
config.context_store = :
|
|
105
|
+
config.context_store = :fiber_local
|
|
94
106
|
config.breadcrumb_capacity = 20
|
|
95
107
|
config.rails_capture_in_test = false
|
|
96
108
|
config.rails_capture_in_console = false
|
|
@@ -102,8 +114,21 @@ Chronos.configure do |config|
|
|
|
102
114
|
config.apm_slow_query_threshold_ms = 500.0
|
|
103
115
|
config.apm_long_transaction_threshold_ms = 1000.0
|
|
104
116
|
config.apm_n_plus_one_threshold = 5
|
|
117
|
+
config.apm_trace_ttl_seconds = 60.0
|
|
118
|
+
config.apm_query_analysis_enabled = true
|
|
119
|
+
config.apm_query_analysis_max_queries = 100
|
|
120
|
+
# Database access is explicit because each inspected fingerprint adds read-only work.
|
|
121
|
+
config.apm_query_inspection_enabled = false
|
|
122
|
+
config.apm_query_statistics_enabled = false
|
|
123
|
+
config.apm_query_plan_enabled = false
|
|
124
|
+
config.apm_query_inspection_min_duration_ms = 500.0
|
|
125
|
+
config.apm_query_inspection_max_queries = 20
|
|
126
|
+
config.apm_transaction_tracking_enabled = true
|
|
127
|
+
config.apm_transaction_max_connections = 100
|
|
105
128
|
config.external_http_enabled = false
|
|
106
129
|
config.external_http_trace_headers = true
|
|
130
|
+
config.w3c_trace_context = false
|
|
131
|
+
config.opentelemetry_bridge = true
|
|
107
132
|
config.cache_key_mode = :none
|
|
108
133
|
config.dependency_reporting = true
|
|
109
134
|
config.dependency_max_items = 100
|
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/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
|
|
@@ -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
|
|
data/docs/modules/context.md
CHANGED
|
@@ -6,7 +6,7 @@ O contexto relaciona uma exceção ou métrica ao request/job atual sem criar de
|
|
|
6
6
|
|
|
7
7
|
## Fluxo e classes
|
|
8
8
|
|
|
9
|
-
`Chronos::Ports::ContextStore` define `get`, `set`, `clear` e `with_context`. Na linha
|
|
9
|
+
`Chronos::Ports::ContextStore` define `get`, `set`, `clear` e `with_context`. Na linha 1.2, `Chronos::Adapters::FiberLocalContextStore` usa storage do Fiber quando disponível e volta com segurança ao adapter thread-local. 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 somente `trace_id`, `span_id`, `trace_flags` e `request_id`.
|
|
10
10
|
|
|
11
11
|
## Extensão, riscos e exemplo
|
|
12
12
|
|
|
@@ -10,6 +10,7 @@ Chronos.configure do |config|
|
|
|
10
10
|
# connection settings omitted
|
|
11
11
|
config.external_http_enabled = true
|
|
12
12
|
config.external_http_trace_headers = true
|
|
13
|
+
config.w3c_trace_context = true
|
|
13
14
|
end
|
|
14
15
|
|
|
15
16
|
http = Net::HTTP.new("payments.example.com", 443)
|
|
@@ -18,10 +19,10 @@ Chronos.instrument_net_http(http)
|
|
|
18
19
|
response = http.request(Net::HTTP::Get.new("/health"))
|
|
19
20
|
```
|
|
20
21
|
|
|
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
|
+
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. With `w3c_trace_context = true`, Net::HTTP and `Chronos::Integrations::FaradayMiddleware` also preserve an existing header or inject a validated `traceparent`. Disable all propagation with `external_http_trace_headers = false`.
|
|
22
23
|
|
|
23
24
|
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
|
|
|
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
|
|
26
|
+
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 is supported through explicit middleware installation; HTTP.rb, Excon, and RestClient remain outside this release.
|
|
26
27
|
|
|
27
28
|
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.
|