exis_ray 0.5.1 → 0.5.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: de4cf609747379030a7d49bf06aea93efbe9d60490eb3d9bfe4af3fec0fe1bd4
4
- data.tar.gz: 0f3cbba6bf49ffec549c1cc7a306b9c018c12196f4a60afd62769268c5f964bf
3
+ metadata.gz: ddc4b5882506b1b65b8b6c6feedfed798b1f810b234f8894165bec04992390c1
4
+ data.tar.gz: d45294e9c7eb72f3e936f93f73240eb6b88526524c9fadea1e599f8561d08413
5
5
  SHA512:
6
- metadata.gz: 5e9532985f27d6ccb4efe76be22b3ff580eb60169e7f7c4a6a9db4ae19ac05a41489d43635f754deb6effd7732c97203ab0e28c19ae845f41f1a284ed79231ec
7
- data.tar.gz: 40796e0043612a9636e212ae4ced8e096a984144e35f4d1e4baa9a1216514f8916ad9f3b2c054852861157015b4d37e9987da5e6b335a34254d0e5b5b8327468
6
+ metadata.gz: b6e9a927b39630af22182153eeaa0130c76d971abf3e57b3d0271ff5b827f2170e49df978ff745daedcaae529b896d555e6f65651ffd758061f471ac087b4a32
7
+ data.tar.gz: d050fb07c85131b1fac04bd588f3b24a43c2f345a9499178004b6458754836dd6ee8bec489b2c403fbdfd2366ddb5480984b4c656fe72e813892cedf2a52dc86
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## [0.5.2] - 2026-03-24
2
+
3
+ ### Added
4
+ - **Official Documentation:** Introduced `MANIFEST.md` as the source of truth for observability standards.
5
+ - **Universal Type-Casting:** Improved `JsonFormatter` to apply automatic numeric casting (Integer/Float) to direct `Hash` inputs, not just KV strings.
6
+ - **Security Hardening:** Documented explicit bans on PII in logs and established valid `source` entrypoint values.
7
+
1
8
  ## [0.5.1] - 2026-03-24
2
9
 
3
10
  ### Fixed
data/CLAUDE.md CHANGED
@@ -4,11 +4,18 @@
4
4
  - `ExisRay::Tracer`: Distributed tracing (AWS X-Ray). Uses `CurrentAttributes` for thread-safety.
5
5
  - `ExisRay::Current`: Business context (User, ISP). Abstract base class for host app subclassing.
6
6
  - `ExisRay::Reporter`: Sentry wrapper. Abstract base class for host app subclassing.
7
- - `ExisRay::JsonFormatter`: Core engine. Handles Hash, KV strings, and free-text with automatic masking.
7
+ - `ExisRay::JsonFormatter`: Core engine. Handles Hash, KV strings, and free-text with automatic masking and **Type Casting**.
8
8
  - `ExisRay::LogSubscriber`: Native HTTP logger since v0.4.0. Replaces Lograge.
9
+ - `ExisRay::TaskMonitor`: Lifecycle manager for non-HTTP processes.
9
10
 
10
11
  ## Technical Knowledge & Compatibility
11
12
 
13
+ ### Wispro Observability Spec (v1)
14
+ - **Manifest:** All logging MUST follow the rules defined in `MANIFEST.md`.
15
+ - **Metrics:** Always use `_s` suffix for durations (Float) and `count` for volumes (Integer). Never include units in values.
16
+ - **Type-Awareness:** `JsonFormatter` automatically casts numeric KV values to Float/Integer. Emit raw numbers in KV strings.
17
+ - **Automatic Fields:** Do not manually log `time`, `level`, `service`, `source`, `root_id`, `correlation_id`, `sidekiq_job` or `task`. These are handled by the library.
18
+
12
19
  ### Rails Compatibility (6, 7, 8)
13
20
  - **Reloading:** Use `cache_classes?` helper (checks `respond_to?(:enable_reloading)`) to avoid deprecation warnings in Rails 7.1+.
14
21
  - **Notifications:** Rails 7.1+ uses `all_listeners_for`, while 6/7.0 uses `listeners_for`. Always use `respond_to?` guards when manipulating subscribers.
@@ -17,11 +24,13 @@
17
24
  - **Propagation:** Use `propagation_trace_header` (standard HTTP format) for outgoing requests.
18
25
  - **Parsing:** `trace_header` (Rack format) is ONLY for incoming request parsing.
19
26
 
20
- ### Security & Privacy
21
- - **Sentry Context:** Default `sentry_user_context` and `sentry_isp_context` to `{ id: }` only. Never send full objects to avoid leaking sensitive fields (PII/Tokens).
22
- - **Masking:** `JsonFormatter` automatically filters `password`, `token`, `api_key`, `auth`, `secret`.
27
+ ## Security & Privacy
28
+ - **Sensitive Key Filtering:** `JsonFormatter` auto-filters keys matching `password|pass|passwd|secret|token|api_key|auth` replaced with `[FILTERED]`.
29
+ - **Header Injection Prevention:** `ExisRay::Current` sanitizes values via `sanitize_header_value` before storing user/ISP identity.
30
+ - **No PII in Logs:** Never log raw user data. Only IDs (`user_id`, `isp_id`) are permitted.
23
31
 
24
32
  ## Execution Rules
25
33
  - **No Lograge:** Do not suggest or re-add the Lograge dependency.
26
- - **Pure Data Logging:** Gem internal logs must use KV strings (`component=exis_ray event=...`).
27
- - **Resilience:** All logging operations must be wrapped in `rescue StandardError` to ensure the host application never crashes due to a telemetry failure.
34
+ - **Pure Data Logging:** Internal logs use KV strings (`component=exis_ray event=...`).
35
+ - **Resilience:** All logging operations must be wrapped in `rescue StandardError`.
36
+ - **Source Values:** Valid values for `source` field: `http`, `sidekiq`, `task`, `system`.
data/MANIFEST.md ADDED
@@ -0,0 +1,96 @@
1
+ # Observability & Telemetry Manifest
2
+
3
+ Este documento define el estándar obligatorio de telemetría y logging estructurado para todo nuestro ecosistema de software. El objetivo es garantizar que cualquier sistema, independientemente de su propósito, emita datos que sean **analizables, consistentes y escalables**.
4
+
5
+ ## Objetivo
6
+ Transformar el logging tradicional en un **flujo de eventos de datos**. Esto permite que herramientas de análisis puedan generar dashboards de rendimiento, alertas inteligentes y rastreo de errores sin necesidad de procesamiento manual de texto o transformaciones complejas.
7
+
8
+ ## Reglas Fundamentales
9
+
10
+ ### 1. Unidad en la Key, Número en el Valor (Data First)
11
+ La regla de oro para que las métricas sean operables es separar la unidad del dato numérico. **Nunca** incluir unidades dentro de los valores de los logs.
12
+ * Incorrecto: `duration="0.5s"`, `memory="128MB"`.
13
+ * Correcto: `duration_s=0.5`, `memory_mb=128`.
14
+
15
+ **Sufijos de unidad recomendados:**
16
+ - `_s`: Segundos (Float). Estándar para duraciones y latencias visibles al negocio.
17
+ - `_ms`: Milisegundos (Integer). Para precisión técnica interna de alta frecuencia.
18
+ - `_count`: Cantidades o volúmenes (Integer). Ej: `record_count`, `retry_count`.
19
+ - `_bytes` / `_kb` / `_mb`: Unidades de almacenamiento o memoria.
20
+ - `_human`: (Opcional) Texto explicativo legible para humanos (ej: `duration_human="2 hours"`).
21
+
22
+ ### 2. Contexto de Identidad
23
+ Cada línea de log debe llevar los metadatos necesarios para identificar su origen técnico de forma inmediata:
24
+ * `component`: Nombre de la gema, librería o módulo responsable (ej: `exis_ray`, `storage_engine`).
25
+ * `event`: Nombre de la acción puntual o hito alcanzado (ej: `http_request`, `engine.complete`).
26
+ * `source`: El punto de entrada de la ejecución (`http`, `sidekiq`, `task`, `system`).
27
+
28
+ ### 3. Convenciones de Naming & Tipos
29
+ - **Naming:** Las llaves (keys) deben usar siempre `snake_case`.
30
+ - **Valores Numéricos:** Deben emitirse como números reales (sin sufijos de texto) para permitir que el motor de logs realice el casting automático.
31
+ - **Formato:** Pares `key=value` en una sola línea estructurada.
32
+
33
+ ---
34
+
35
+ ## Infraestructura de Datos (Automática)
36
+
37
+ La gema `exis_ray` inyecta automáticamente los siguientes metadatos en cada línea de log JSON, por lo que **no deben incluirse manualmente** en los mensajes:
38
+
39
+ | Llave | Descripción | Origen |
40
+ | :--- | :--- | :--- |
41
+ | `time` | Marca de tiempo en formato ISO8601 UTC. | Logger |
42
+ | `level` | Nivel de severidad (INFO, ERROR, DEBUG, etc.). | Logger |
43
+ | `service` | Nombre de la aplicación en `snake_case`. | Tracer |
44
+ | `source` | Entrypoint: `http`, `sidekiq`, `task` o `system`. | Tracer |
45
+ | `root_id` | Identificador único de la traza distribuida (AWS X-Ray). | Tracer |
46
+ | `correlation_id` | ID compuesto para rastreo cruzado. | Tracer |
47
+ | `user_id` / `isp_id` | Identidad del sujeto de negocio (si está presente). | Current |
48
+ | `sidekiq_job` | Nombre de la clase del Worker (solo en Sidekiq). | Tracer |
49
+ | `task` | Nombre de la tarea Rake o Cron (solo en TaskMonitor). | Tracer |
50
+
51
+ ---
52
+
53
+ ## Ciclo de Vida del Evento
54
+
55
+ ### Procesos, Trabajos y Tareas (Jobs/Tasks)
56
+ Todo proceso aislado debe reportar su inicio y su finalización con una estructura consistente:
57
+ - `event`: Identificador de estado (ej: `task_started`, `task_finished`).
58
+ - `status`: Resultado final de la operación (`success`, `failed`, `aborted`). En contexto de tareas/jobs, siempre es un string semántico, no un código HTTP.
59
+ - `duration_s`: Tiempo total de ejecución (calculado con reloj monotónico).
60
+ - `error_class` / `error_message`: Obligatorios solo en caso de fallo.
61
+
62
+ ### Peticiones de Interfaz (APIs/HTTP)
63
+ Los logs de cierre de peticiones deben estandarizar el reporte de rendimiento para telemetría:
64
+ - `status`: Código de respuesta HTTP (Integer). En contexto HTTP siempre es el código numérico (ej: `200`, `404`, `500`).
65
+ - `duration_s`: Tiempo total de respuesta del servidor.
66
+ - `[subsystem]_runtime_s`: Desglose opcional de tiempos por capa (ej: `db_runtime_s`, `view_runtime_s`).
67
+
68
+ ---
69
+
70
+ ## Ejemplo de Implementación Estándar
71
+
72
+ **En el código fuente:**
73
+ ```ruby
74
+ # Reporte de éxito con métricas integradas
75
+ logger.info "component=data_processor event=sync_complete status=success duration_s=1.25 record_count=500"
76
+
77
+ # Reporte de error con contexto técnico
78
+ logger.error "component=data_processor event=sync_complete status=failed error_class=Timeout error_message=\"Server reset\""
79
+ ```
80
+
81
+ **Resultado JSON unificado:**
82
+ ```json
83
+ {
84
+ "time": "2026-03-24T14:00:00Z",
85
+ "level": "INFO",
86
+ "service": "my_application",
87
+ "component": "data_processor",
88
+ "event": "sync_complete",
89
+ "status": "success",
90
+ "duration_s": 1.25,
91
+ "record_count": 500,
92
+ "source": "task",
93
+ "root_id": "Root=1-...",
94
+ "correlation_id": "my_application;Root=..."
95
+ }
96
+ ```
@@ -165,7 +165,7 @@ module ExisRay
165
165
  result[k] = if v.is_a?(Hash)
166
166
  filter_sensitive_hash(v)
167
167
  else
168
- filter_sensitive_value(k, v)
168
+ cast_value(k, v)
169
169
  end
170
170
  end
171
171
  end
@@ -2,5 +2,5 @@
2
2
 
3
3
  module ExisRay
4
4
  # Versión actual de la gema.
5
- VERSION = "0.5.1"
5
+ VERSION = "0.5.2"
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: exis_ray
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gabriel Edera
@@ -48,6 +48,7 @@ files:
48
48
  - CHANGELOG.md
49
49
  - CLAUDE.md
50
50
  - LICENSE.txt
51
+ - MANIFEST.md
51
52
  - README.md
52
53
  - Rakefile
53
54
  - lib/exis_ray.rb