chronos-ruby 0.9.0.pre.3 → 1.0.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 +34 -0
- data/README.md +101 -181
- data/contracts/integration-verification-response-v1.schema.json +76 -0
- 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-018-pre-1.0-hardening.md +6 -2
- data/docs/compatibility.md +30 -23
- data/docs/data-collected.md +3 -0
- data/docs/deprecation-policy.md +1 -1
- data/docs/migration-from-airbrake.md +1 -1
- data/docs/modules/breadcrumbs.md +23 -0
- data/docs/modules/context.md +21 -0
- data/docs/modules/deploys.md +23 -0
- data/docs/modules/integration-verification.md +65 -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 +22 -0
- data/docs/performance.md +13 -2
- data/docs/protocol-v1.md +3 -1
- data/docs/release-1.0-readiness.md +17 -15
- data/docs/security-review.md +4 -3
- data/docs/troubleshooting.md +6 -0
- data/lib/chronos/adapters/net_http_transport.rb +36 -2
- data/lib/chronos/agent.rb +21 -0
- data/lib/chronos/application/delivery_pipeline.rb +6 -3
- data/lib/chronos/application/verify_integration.rb +262 -0
- data/lib/chronos/core/integration_verification_result.rb +108 -0
- data/lib/chronos/errors.rb +11 -0
- data/lib/chronos/ports/transport.rb +18 -1
- data/lib/chronos/rails/railtie.rb +5 -0
- data/lib/chronos/rake_tasks.rb +41 -0
- data/lib/chronos/version.rb +1 -1
- data/lib/chronos.rb +26 -0
- metadata +35 -4
|
@@ -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.
|
|
@@ -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.
|
data/docs/compatibility.md
CHANGED
|
@@ -1,36 +1,43 @@
|
|
|
1
1
|
# Compatibility
|
|
2
2
|
|
|
3
|
-
Chronos Ruby 0
|
|
3
|
+
Chronos Ruby 1.0 is the stable legacy line. Technical compatibility does not make an end-of-life Ruby, Rails, Rack, or Sidekiq release secure.
|
|
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. The green candidate evidence that permitted the 1.0 promotion is recorded in [Version 1.0 readiness](release-1.0-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.0 pair is advertised this way.
|
|
35
42
|
- Deprecated: still tested while removal is planned.
|
|
36
|
-
- Unsupported: outside
|
|
43
|
+
- Unsupported: outside the tested 1.0 contract.
|
data/docs/data-collected.md
CHANGED
|
@@ -48,6 +48,7 @@ Version 0.9 emits exceptions, cache telemetry, dependency/deploy events, and agg
|
|
|
48
48
|
| Rails, web server, database adapter, Sidekiq, release | Included when safely detectable/configured | Loaded constants/specs and `app_version` |
|
|
49
49
|
| Event release, revision, deploy ID, environment, service, region, instance | Present as bounded correlation; values optional | Explicit immutable configuration or normalized deploy payload |
|
|
50
50
|
| Deploy environment, revision, version, repository, actor, deploy ID, service, region, instance | Explicit synchronous deploy API | Application/deployment integration arguments |
|
|
51
|
+
| 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 |
|
|
51
52
|
|
|
52
53
|
The gem never collects 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, raw cache keys/values, mail bodies/recipients, Active Job arguments, gem paths, or lockfile contents. Active Job IDs, Sidekiq JIDs/arguments, loaded gem names/versions, and deploy fields are documented integration data.
|
|
53
54
|
|
|
@@ -55,4 +56,6 @@ APM dimensions never include user ID, job ID, raw URL, exception message, bind v
|
|
|
55
56
|
|
|
56
57
|
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.
|
|
57
58
|
|
|
59
|
+
The integration check uses the fixed class `Chronos::IntegrationVerificationError`, tag/fingerprint `chronos-integration-verification`, and `context.integration_verification.test: true`. Its returned object allowlists only project identity/status/environment, receiver name/status/receipt time, correlation IDs, booleans, and safe guidance. Raw response bodies and Chronos implementation details are discarded.
|
|
60
|
+
|
|
58
61
|
See [Privacy and LGPD](privacy-lgpd.md) for redaction rules and the payload audit procedure.
|
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.
|
|
@@ -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
|
|---|---|
|
|
@@ -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,65 @@
|
|
|
1
|
+
# Integration verification
|
|
2
|
+
|
|
3
|
+
`Chronos.verify_integration` performs an explicit end-to-end check of configuration, credentials, receiver availability, and ingestion acknowledgement. Rails registers `chronos:verify_integration` automatically through the Railtie. The command prints exactly one JSON object and exits nonzero unless verification succeeds.
|
|
4
|
+
|
|
5
|
+
## Flow and ownership
|
|
6
|
+
|
|
7
|
+
`Chronos::Application::VerifyIntegration` creates one normal v1 exception envelope, delivers it synchronously through `DeliveryPipeline`, and validates the response. `IntegrationVerificationResult` exposes the immutable, bounded public outcome. `RakeTasks` only loads the application environment, calls the facade, prints JSON, and selects the exit status.
|
|
8
|
+
|
|
9
|
+
The synthetic event is recognizable without changing the event protocol:
|
|
10
|
+
|
|
11
|
+
```json
|
|
12
|
+
{
|
|
13
|
+
"event_type": "exception",
|
|
14
|
+
"payload": {
|
|
15
|
+
"exception": {"class": "Chronos::IntegrationVerificationError"},
|
|
16
|
+
"tags": ["chronos-integration-verification"],
|
|
17
|
+
"fingerprint": "chronos-integration-verification"
|
|
18
|
+
},
|
|
19
|
+
"context": {
|
|
20
|
+
"integration_verification": {
|
|
21
|
+
"schema_version": "1.0",
|
|
22
|
+
"verification_id": "generated-uuid",
|
|
23
|
+
"kind": "integration_verification",
|
|
24
|
+
"test": true
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Chronos must authenticate before acknowledging the event and must correlate both `verification_id` and the envelope event ID. A `2xx` response alone is insufficient. The accepted response must conform exactly to [`integration-verification-response-v1.schema.json`](../../contracts/integration-verification-response-v1.schema.json):
|
|
31
|
+
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"schema_version": "1.0",
|
|
35
|
+
"success": true,
|
|
36
|
+
"status": "accepted",
|
|
37
|
+
"verification_id": "generated-uuid",
|
|
38
|
+
"credentials_valid": true,
|
|
39
|
+
"event_received": true,
|
|
40
|
+
"event": {"id": "event-uuid"},
|
|
41
|
+
"project": {"id": "project-id", "name": "Project", "status": "active", "environment": "production"},
|
|
42
|
+
"receiver": {"name": "chronos", "status": "operational", "received_at": "2026-07-22T12:00:00Z"},
|
|
43
|
+
"error": null
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The client rejects missing, mismatched, or additional fields. It copies only the allowlisted project and receiver values and never returns the raw body.
|
|
48
|
+
|
|
49
|
+
## Result and failure classification
|
|
50
|
+
|
|
51
|
+
The Ruby result supports `success?`, `to_h`, and `to_json`. Its status is `verified` only after the correlated acknowledgement. Failures use `configuration_invalid`, `invalid_credentials`, `project_inactive`, `receiver_unavailable`, `receiver_internal_error`, `rate_limited`, `request_rejected`, `invalid_response`, or `verification_failed`.
|
|
52
|
+
|
|
53
|
+
- `401` and untrusted `403` responses become `invalid_credentials` with instructions to create an active project API key and verify the configured identifiers.
|
|
54
|
+
- A contractual authenticated `403` response may become `project_inactive`.
|
|
55
|
+
- network errors, timeouts, an open circuit, and `502`/`503`/`504` become `receiver_unavailable`.
|
|
56
|
+
- other `5xx` responses become `receiver_internal_error`.
|
|
57
|
+
- malformed or uncorrelated success responses become `invalid_response`.
|
|
58
|
+
|
|
59
|
+
Failure output uses local messages and guidance. Server exception messages, stack traces, SQL, paths, classes, credentials, response headers, and architecture details are never copied.
|
|
60
|
+
|
|
61
|
+
## Usage
|
|
62
|
+
|
|
63
|
+
In Rails, configure Chronos normally and run `bundle exec rake chronos:verify_integration`. In plain Ruby, require `chronos/rake_tasks` and call `Chronos::RakeTasks.install` from the Rakefile. Programmatic callers can use `Chronos.verify_integration` directly.
|
|
64
|
+
|
|
65
|
+
Verification is an explicit synchronous diagnostic operation. It bypasses sampling and ignore rules so an operator-requested check cannot silently disappear, but it still uses the configured bounded retry, timeout, TLS, circuit, serializer, and transport protections. The receiver should record it as a verification/audit receipt rather than a production application incident.
|
|
@@ -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`.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Informações de runtime
|
|
2
|
+
|
|
3
|
+
## Problema e limite
|
|
4
|
+
|
|
5
|
+
O agente identifica o runtime necessário para diagnóstico e inventário sem varrer o ambiente, o sistema de arquivos ou conexões da aplicação. A versão 1.0 não implementa profiling nem coleta contínua de CPU/RSS.
|
|
6
|
+
|
|
7
|
+
## Fluxo e classes
|
|
8
|
+
|
|
9
|
+
`Chronos::Core::RuntimeInfo` produz engine, versão, plataforma, PID, thread opaca e hostname permitido. `DependencyReporter` adiciona versões já carregadas de Ruby, Rails, servidor, adaptador de banco e Sidekiq em um evento separado e limitado, no máximo uma vez por agente e após deploy bem-sucedido.
|
|
10
|
+
|
|
11
|
+
## Extensão, riscos e exemplo
|
|
12
|
+
|
|
13
|
+
Aplicações podem configurar versão, release, região e instância explicitamente. Hostname, IDs de processo e inventário podem ser dados pessoais ou revelar topologia; desative `dependency_reporting` quando a finalidade não justificar a coleta.
|
|
14
|
+
|
|
15
|
+
```ruby
|
|
16
|
+
Chronos.configure do |config|
|
|
17
|
+
config.dependency_reporting = false
|
|
18
|
+
config.app_version = "2026.07.29"
|
|
19
|
+
end
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Veja `spec/unit/core/runtime_info_spec.rb`, `spec/unit/application/dependency_reporter_spec.rb` e `spec/integration/dependency_delivery_spec.rb`.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Sampling
|
|
2
|
+
|
|
3
|
+
## Problema e limite
|
|
4
|
+
|
|
5
|
+
Sampling reduz volume de eventos sem permitir que o servidor amplie a coleta decidida localmente. Ele não substitui quotas no receptor e não deve ser usado para esconder falhas do agente.
|
|
6
|
+
|
|
7
|
+
## Fluxo e classes
|
|
8
|
+
|
|
9
|
+
`Chronos::Configuration` valida `sampling_rate` entre `0.0` e `1.0`. `Chronos::Application::RemoteConfiguration` calcula o limite efetivo, que nunca excede o valor local, e `DeliveryPipeline` decide antes do transporte. Deploys e verificações explícitas usam seus próprios caminhos síncronos e não são descartados pelo sampling comum.
|
|
10
|
+
|
|
11
|
+
## Extensão, riscos e exemplo
|
|
12
|
+
|
|
13
|
+
O gerador aleatório pode ser injetado nos objetos internos para testes determinísticos; a API pública expõe somente a taxa. Taxas baixas podem ocultar eventos raros e não garantem amostragem estatística estratificada.
|
|
14
|
+
|
|
15
|
+
```ruby
|
|
16
|
+
Chronos.configure do |config|
|
|
17
|
+
config.sampling_rate = 0.25
|
|
18
|
+
config.remote_configuration = true
|
|
19
|
+
end
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
O comportamento é coberto por `spec/unit/application/remote_configuration_spec.rb`, `spec/unit/application/delivery_pipeline_spec.rb` e `spec/integration/deploy_delivery_spec.rb`.
|
|
@@ -4,7 +4,7 @@ Version `0.6.0.pre.1` starts the legacy jobs line with optional Sidekiq 4 and 5
|
|
|
4
4
|
|
|
5
5
|
```ruby
|
|
6
6
|
gem "sidekiq", "~> 5.0"
|
|
7
|
-
gem "chronos-ruby", "0.
|
|
7
|
+
gem "chronos-ruby", "~> 1.0.0", :require => "chronos/sidekiq"
|
|
8
8
|
```
|
|
9
9
|
|
|
10
10
|
`chronos/sidekiq` installs middleware through the public `configure_client` and `configure_server` APIs. It does nothing when Sidekiq is unavailable, and the core gem never requires Sidekiq. Installation adds no Chronos thread or Redis/database connection per job; delivery continues through the agent's existing fixed worker pool.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Monitoramento SQL
|
|
2
|
+
|
|
3
|
+
## Problema e limite
|
|
4
|
+
|
|
5
|
+
O monitoramento SQL mede operação, tabela e duração sem transmitir SQL bruto ou binds. Sinais locais de lentidão, repetição, possível N+1, transação longa, conexão e deadlock são diagnósticos heurísticos.
|
|
6
|
+
|
|
7
|
+
## Fluxo e classes
|
|
8
|
+
|
|
9
|
+
`Rails::NotificationsSubscriber` extrai somente campos permitidos. `Core::SqlNormalizer` remove comentários e literais, limita identificadores e calcula fingerprint SHA-256. `ApmAggregator` mantém grupos e fingerprints por trace com capacidades fixas, então drena lotes pelo pipeline comum.
|
|
10
|
+
|
|
11
|
+
## Extensão, riscos e exemplo
|
|
12
|
+
|
|
13
|
+
Thresholds podem ser configurados, mas dimensões de alta cardinalidade não devem ser adicionadas. Nomes de schema, tabela e coluna ainda podem revelar domínio e precisam de avaliação LGPD.
|
|
14
|
+
|
|
15
|
+
```ruby
|
|
16
|
+
Chronos.configure do |config|
|
|
17
|
+
config.apm_slow_query_threshold_ms = 500.0
|
|
18
|
+
config.apm_n_plus_one_threshold = 5
|
|
19
|
+
end
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Veja `spec/unit/core/sql_normalizer_spec.rb`, `spec/unit/application/apm_aggregator_spec.rb` e `spec/integration/rails_telemetry_delivery_spec.rb`.
|
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 1.0 makes no unverified speed claim.
|
|
4
4
|
|
|
5
5
|
Current controls:
|
|
6
6
|
|
|
@@ -29,7 +29,7 @@ Current controls:
|
|
|
29
29
|
|
|
30
30
|
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.
|
|
31
31
|
|
|
32
|
-
## Version 0.
|
|
32
|
+
## Version 1.0.0 release gates
|
|
33
33
|
|
|
34
34
|
`benchmarks/comparative.rb` compares the same successful Rack fixture without and with Chronos instrumentation. It performs configurable warmup, at least three samples, and reports median plus median absolute deviation. `benchmarks/fake_endpoint_load.rb` sends asynchronous exception events to a local TCP endpoint, verifies the v1 schema marker, ensures the secret key is absent from every payload, and fails on loss, rejection, invalid payload, or timeout.
|
|
35
35
|
|
|
@@ -40,6 +40,17 @@ ITERATIONS=500 bundle exec ruby benchmarks/fake_endpoint_load.rb
|
|
|
40
40
|
|
|
41
41
|
Results are environment-specific evidence, not a general speed claim. Record CPU, OS, Ruby, gem commit, and environment variables with any published result. Airbrake comparison remains optional and must use a legally compatible, equivalent sanitized payload on the same supported runtime.
|
|
42
42
|
|
|
43
|
+
### Stable candidate measurement
|
|
44
|
+
|
|
45
|
+
The 1.0 candidate was measured on 2026-07-29 on an Apple Silicon arm64 host running macOS 26.6, with Ruby 2.2.10 executing as x86_64. The working tree was based on commit `ce7c67852dd39406f514499b0347a67c5b09bb8c` plus the 1.0 release changes. This is release-gate evidence for this environment, not a universal performance claim.
|
|
46
|
+
|
|
47
|
+
| Gate | Configuration | Result |
|
|
48
|
+
|---|---|---|
|
|
49
|
+
| Rack comparison | 1,000 warmup calls, 10,000 calls/sample, 5 samples | direct median 0.016036 s (MAD 0.000187); Chronos median 0.482321 s (MAD 0.016988); median incremental work 46.628 µs/request |
|
|
50
|
+
| Fake endpoint load | 500 asynchronous exceptions, 2 workers, queue 500 | 500/500 accepted and received, zero invalid/secret-bearing payloads, 1.444941 s, 346.03 events/s |
|
|
51
|
+
|
|
52
|
+
The release workflow repeats both gates on the tag. It does not enforce a cross-hardware timing threshold; correctness, bounded delivery, complete receipt, privacy and repeatability are hard failures, while timing regressions are reviewed with the recorded environment.
|
|
53
|
+
|
|
43
54
|
## Version 0.5 Rails subscriber benchmark
|
|
44
55
|
|
|
45
56
|
Run:
|
data/docs/protocol-v1.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Protocol v1 stability
|
|
2
2
|
|
|
3
|
-
The schemas under `contracts/` are the source of truth for protocol v1. Version `0.
|
|
3
|
+
The schemas under `contracts/` are the source of truth for protocol v1. Version `1.0.0` freezes `schema_version: "1.0"` and treats every required field, enum value, privacy exclusion, and maximum as a compatibility contract.
|
|
4
4
|
|
|
5
5
|
Compatible changes may add optional bounded fields or new event types accepted by the server. Removing or renaming a field, changing its type/meaning, weakening a bound, or making an optional field required needs a new protocol major schema. Authentication remains outside the JSON payload. Contract tests and `script/verify_docs` must pass before a release.
|
|
6
|
+
|
|
7
|
+
The explicit integration check uses the normal exception envelope and identifies itself through `context.integration_verification`. Its receiver acknowledgement is governed separately by [`integration-verification-response-v1.schema.json`](../contracts/integration-verification-response-v1.schema.json). A successful HTTP status without a complete, correlated response is not proof of authentication or ingestion.
|
|
@@ -1,18 +1,20 @@
|
|
|
1
|
-
# Version 1.0
|
|
1
|
+
# Version 1.0 release evidence
|
|
2
2
|
|
|
3
|
-
Version `0.
|
|
3
|
+
Version `1.0.0` is the first stable legacy release. Promotion was based on the complete candidate commit `ce7c67852dd39406f514499b0347a67c5b09bb8c`; future tags must pass the same gates again inside the release workflow before publishing.
|
|
4
4
|
|
|
5
|
-
| Gate |
|
|
6
|
-
|
|
7
|
-
| Ruby
|
|
8
|
-
|
|
|
9
|
-
|
|
|
10
|
-
|
|
|
11
|
-
|
|
|
12
|
-
|
|
|
13
|
-
|
|
|
14
|
-
|
|
|
15
|
-
|
|
|
16
|
-
|
|
|
5
|
+
| Gate | Evidence for the candidate | Enforcement for the tag |
|
|
6
|
+
|---|---|---|
|
|
7
|
+
| Ruby 2.2.10–2.6.10 | [Legacy CI: success](https://github.com/antoniojefferson/chronos-ruby/actions/runs/29891291304) | `legacy-core` matrix |
|
|
8
|
+
| Rails 4.2/5.2 applications | [Legacy Rails CI: success](https://github.com/antoniojefferson/chronos-ruby/actions/runs/29891291287) | `legacy-rails` matrix |
|
|
9
|
+
| Sidekiq 4/5 real gems | [Legacy Sidekiq CI: success](https://github.com/antoniojefferson/chronos-ruby/actions/runs/29891291327) | `legacy-sidekiq` matrix |
|
|
10
|
+
| Documentation and package | [Repository checks: success](https://github.com/antoniojefferson/chronos-ruby/actions/runs/29891291350) | `release-readiness` plus publish build |
|
|
11
|
+
| Dependency audit | [Security: success](https://github.com/antoniojefferson/chronos-ruby/actions/runs/30251211355) | scheduled and pull-request security workflow |
|
|
12
|
+
| Unit/integration/contracts/lint | 179 examples, 0 failures; 197 files, 0 offenses on Ruby 2.2.10 | every core matrix job |
|
|
13
|
+
| Payload privacy | Contract tests reject secrets in payload and retry backlog | every core matrix job and fake-endpoint load gate |
|
|
14
|
+
| API/options/protocol | Public facade, configuration table, v1 schemas, SemVer and deprecation policy reviewed | documentation verifier and contract suite |
|
|
15
|
+
| Airbrake migration | Staged migration and rollback guide | documentation verifier |
|
|
16
|
+
| Load and repeatable comparison | Local bounded fake endpoint plus median/MAD Rack comparison | `release-readiness` job |
|
|
17
|
+
| Security/release artifacts | Security review, Trusted Publishing, SHA-256 and SPDX SBOM | publish job after all dependencies pass |
|
|
18
|
+
| Package signing | Not currently feasible without a trusted key lifecycle | documented residual control: OIDC publishing, checksum and SBOM |
|
|
17
19
|
|
|
18
|
-
|
|
20
|
+
`publish` depends on all four release jobs. A failed or skipped supported runtime/framework/job pair, documentation check, comparison, or load test prevents RubyGems publication.
|
data/docs/security-review.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# Security review for 0.
|
|
1
|
+
# Security review for 1.0.0
|
|
2
2
|
|
|
3
|
-
Review date: 2026-07-
|
|
3
|
+
Review date: 2026-07-29. Scope: capture, serialization, transport, integration verification, remote configuration, framework/job integrations, stable release workflow, examples, and fixtures.
|
|
4
4
|
|
|
5
5
|
Verified by contracts and implementation review:
|
|
6
6
|
|
|
@@ -12,5 +12,6 @@ Verified by contracts and implementation review:
|
|
|
12
12
|
- integrations contain agent failures and do not collect bodies, authorization, raw SQL/binds, mail content, or raw cache keys;
|
|
13
13
|
- Active Job propagation uses a namespaced v1 field containing only bounded trace/request identifiers and does not alter job arguments;
|
|
14
14
|
- fixture privacy is enforced by contract tests and dependency advisories are checked by the security workflow.
|
|
15
|
+
- integration verification accepts only a strict correlated response and never exposes raw receiver bodies, credentials, stack traces, paths, SQL, or internal architecture.
|
|
15
16
|
|
|
16
|
-
Residual risks: supported Ruby/Rails versions are end-of-life; in-memory backlog is lost at exit; application filters/ignore rules execute application code; project identifiers and documented job IDs may be personal data in some deployments; package signing is not enabled because no trusted certificate/key lifecycle exists.
|
|
17
|
+
Residual risks: supported Ruby/Rails versions are end-of-life; in-memory backlog is lost at exit; application filters/ignore rules execute application code; project identifiers and documented job IDs may be personal data in some deployments; package signing is not enabled because no trusted certificate/key lifecycle exists. Stable artifacts use a protected environment, Trusted Publishing, SHA-256 checksums and SPDX SBOMs until signing can be operated safely.
|
data/docs/troubleshooting.md
CHANGED
|
@@ -12,6 +12,12 @@ The agent may be unconfigured, disabled, ignored in the current environment, una
|
|
|
12
12
|
|
|
13
13
|
Check DNS, TLS certificates, credentials, HTTP status, proxy configuration, and timeout values. The resilience layer retries only network errors, HTTP `408`, `429`, and `5xx` responses. Inspect `agent.diagnostics` when constructing an agent directly to see retry state, backlog usage, and the circuit state.
|
|
14
14
|
|
|
15
|
+
## `chronos:verify_integration` fails
|
|
16
|
+
|
|
17
|
+
Read the single JSON object printed by the task and use `status` and `error.guidance`. `invalid_credentials` means an active project API key must be created or the configured `project_id`/`project_key` corrected. `project_inactive` means authentication succeeded but the selected project must be activated. `receiver_unavailable` covers DNS, TLS, network, timeout, circuit-open, and gateway/service-unavailable failures. `receiver_internal_error` means Chronos reached its own safe internal-error boundary. `invalid_response` means the receiver did not implement the correlated response v1 contract. Every failure exits nonzero and deliberately omits raw receiver messages and implementation details.
|
|
18
|
+
|
|
19
|
+
If Rails does not list the task, require `chronos/rails` and confirm the application initializer loads. A `not_configured` result means the current Rake process did not execute `Chronos.configure`; update to a release containing the Rails environment prerequisite fix and confirm the variables are exported into that process. In plain Ruby, require `chronos/rake_tasks` and call `Chronos::RakeTasks.install` from the Rakefile after loading configuration.
|
|
20
|
+
|
|
15
21
|
## Rack exception is not captured
|
|
16
22
|
|
|
17
23
|
Confirm that `Chronos.configure` runs before the middleware handles requests and that the middleware wraps the application component that raises. Version 0.5 captures exceptions raised by the initial downstream Rack call; an exception raised later while a server enumerates a streaming response body is outside this release. The original exception is always re-raised, so the server log should still show it.
|