exis_ray 0.10.0 → 0.11.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 +7 -0
- data/CLAUDE.md +1 -0
- data/README.md +30 -3
- data/lib/exis_ray/configuration.rb +21 -0
- data/lib/exis_ray/log_subscriber.rb +13 -7
- data/lib/exis_ray/task_monitor.rb +21 -4
- data/lib/exis_ray/version.rb +1 -1
- data/skill/SKILL.md +10 -6
- data/spec/exis_ray/configuration_spec.rb +22 -0
- data/spec/exis_ray/log_subscriber_spec.rb +43 -0
- data/spec/exis_ray/task_monitor_spec.rb +15 -0
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e474f1122d88cba11551996f1fe73b01da92f28dcea658e6eb473e51277e838e
|
|
4
|
+
data.tar.gz: 708af8ed6b2ece0cf5e78f74543135ceb4e83d8e2e51788e980847c7675d586e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2e314e520ab390a510953c78c8774c816e30a9fd814e9bbd36eb2e874e5ed81abbaeb91a7f0abea350c46f4783f8f93c176209a08a15a4691de2c13551534135
|
|
7
|
+
data.tar.gz: 478cfe36c1b7f5e60c37de8c6db1e86c239a13a2ec2c8a3bd6797b455cc27dd0ed7f3960c02e29049e0979c648a7ab7857982d84664ae43647dfb2af5cb99f16
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
## [0.11.0] - 2026-05-26
|
|
2
|
+
|
|
3
|
+
### Nuevas funcionalidades
|
|
4
|
+
- **`config.emit_legacy_exception_keys`** (#15): nuevo flag de `Configuration` (default `true`) que controla la emisión de las keys legacy `error_class`/`error_message` junto a `exception.type`/`exception.message`. Bajado a `false`, `ExisRay::LogSubscriber` (logs HTTP) y `ExisRay::TaskMonitor` (logs de tasks) emiten solo las keys OTel v1.0 (`exception.*`), reduciendo bytes y ruido downstream cuando los consumers (dashboards, alertas, queries) ya migraron. Mantiene `true` como default durante la ventana de transición — se flipea a `false` en v0.12.0 y se remueve el flag en v1.0 cuando los legacy se eliminen definitivamente.
|
|
5
|
+
- **`url.path` (OTel v1.0) + `config.emit_legacy_path_key`** (#15): `ExisRay::LogSubscriber` empieza a emitir `url.path` (nombre canónico OTel) en todos los logs HTTP. El alias legacy `path` se sigue emitiendo durante la ventana de transición y queda gateado por `config.emit_legacy_path_key` (default `true`). Cuando los consumers (queries, dashboards, alertas) hayan migrado a `url.path`, bajar el flag a `false` para suprimir el alias. Se flipea a `false` en v0.12.0 y se remueve el flag en v1.0.
|
|
6
|
+
- **Doc: `url.path` vs `http_route` no se deduplican** (#15): el caso reportado de "valores idénticos en endpoints estáticos" no es un bug — `url.path` es la URL **concreta** (alta cardinalidad), `http_route` es el **template** (baja cardinalidad). Cumplen roles distintos en dashboards/queries downstream; siguen emitiéndose siempre los dos. Documentado en `README.md` y `skill/SKILL.md` (subsección "Migración OTel — `path` → `url.path`" + nota explicativa de la coexistencia semántica).
|
|
7
|
+
|
|
1
8
|
## [0.10.0] - 2026-05-25
|
|
2
9
|
|
|
3
10
|
### Documentación
|
data/CLAUDE.md
CHANGED
|
@@ -178,6 +178,7 @@ ExisRay.configure do |config|
|
|
|
178
178
|
config.propagation_trace_header = 'X-Amzn-Trace-Id'
|
|
179
179
|
config.current_class = 'Current'
|
|
180
180
|
config.reporter_class = 'Reporter'
|
|
181
|
+
config.emit_legacy_exception_keys = true # default true; pasar a false cuando consumers usen exception.*
|
|
181
182
|
end
|
|
182
183
|
|
|
183
184
|
# BugBunny publisher — debe agregarse manualmente al cliente
|
data/README.md
CHANGED
|
@@ -370,8 +370,9 @@ config.logger.formatter = ExisRay::JsonFormatter
|
|
|
370
370
|
| `component` | String | Siempre `"exis_ray"` |
|
|
371
371
|
| `event` | String | Siempre `"http_request"` |
|
|
372
372
|
| `method` | String | Verbo HTTP |
|
|
373
|
-
| `path` | String | URL concreta del request |
|
|
374
|
-
| `
|
|
373
|
+
| `url.path` | String | URL concreta del request (OTel v1.0). Siempre presente |
|
|
374
|
+
| `path` | String | Alias legacy de `url.path`. Solo si `config.emit_legacy_path_key` (default `true`, deprecado) |
|
|
375
|
+
| `http_route` | String | Template (ej: `/users/:id`). Baja cardinalidad para dashboards. En endpoints sin params coincide en valor con `url.path` — la dupe es semánticamente esperada (concrete vs template) |
|
|
375
376
|
| `format` | Symbol/String | `html`, `json`, etc. |
|
|
376
377
|
| `controller` | String | Class name del controller |
|
|
377
378
|
| `action` | String | Nombre del action |
|
|
@@ -382,11 +383,37 @@ config.logger.formatter = ExisRay::JsonFormatter
|
|
|
382
383
|
| `db_runtime_s` | Float\|nil | Solo si ActiveRecord lo reporta |
|
|
383
384
|
| `user_agent_original` | String | Header `User-Agent` |
|
|
384
385
|
| `server_address` | String | Hostname sin puerto del header `Host` |
|
|
385
|
-
| `error_class`, `error_message` | String | Solo en fallo (
|
|
386
|
+
| `error_class`, `error_message` | String | Solo en fallo y si `config.emit_legacy_exception_keys` (default `true`, deprecadas) |
|
|
386
387
|
| `exception.type`, `exception.message`, `exception.stacktrace` | String | Solo en fallo (OTel; stack limitado a 20 líneas) |
|
|
387
388
|
|
|
388
389
|
Severity del log: `ERROR` si `http_status >= 500`, sino `INFO`.
|
|
389
390
|
|
|
391
|
+
### Migración OTel — `error_class`/`error_message` → `exception.*`
|
|
392
|
+
|
|
393
|
+
Durante la ventana de transición OTel v1.0, `LogSubscriber` y `TaskMonitor` emiten ambos sets de keys en cada log de error. Cuando todos los consumers (dashboards, queries, alertas) hayan migrado a `exception.type`/`exception.message`/`exception.stacktrace`, desactivar los legacy:
|
|
394
|
+
|
|
395
|
+
```ruby
|
|
396
|
+
ExisRay.configure do |c|
|
|
397
|
+
c.emit_legacy_exception_keys = false # default: true
|
|
398
|
+
end
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
Roadmap: default `false` en v0.12.0; flag y legacy keys removidos en v1.0.
|
|
402
|
+
|
|
403
|
+
### Migración OTel — `path` → `url.path`
|
|
404
|
+
|
|
405
|
+
`LogSubscriber` emite `url.path` (nombre OTel v1.0) en todos los logs HTTP. Durante la ventana de transición emite también `path` (alias legacy Wispro). Cuando las queries/dashboards/alertas migren a `url.path`, desactivar el legacy:
|
|
406
|
+
|
|
407
|
+
```ruby
|
|
408
|
+
ExisRay.configure do |c|
|
|
409
|
+
c.emit_legacy_path_key = false # default: true
|
|
410
|
+
end
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
Roadmap: default `false` en v0.12.0; flag y key `path` removidos en v1.0.
|
|
414
|
+
|
|
415
|
+
> **Sobre `url.path` vs `http_route`:** son semánticamente distintos — `url.path` es la URL **concreta** (alta cardinalidad, ej. `/users/42`), `http_route` es el **template** matcheado (baja cardinalidad, ej. `/users/:id`). En endpoints sin params coinciden en valor (ej. `/up`), pero ambos se siguen emitiendo porque cumplen roles distintos en dashboards/queries downstream. La dupe en valor es esperada, no es un bug.
|
|
416
|
+
|
|
390
417
|
### Filtrado de claves sensibles
|
|
391
418
|
|
|
392
419
|
Las claves que matcheen `/password|pass|passwd|secret|token|api_key|auth/i` se reemplazan automáticamente por `[FILTERED]`, tanto en strings KV como en Hashes (incluyendo anidados).
|
|
@@ -52,6 +52,25 @@ module ExisRay
|
|
|
52
52
|
# @example 'production'
|
|
53
53
|
attr_accessor :deployment_environment
|
|
54
54
|
|
|
55
|
+
# @!attribute [rw] emit_legacy_exception_keys
|
|
56
|
+
# @return [Boolean] Si true, emite `error_class`/`error_message` junto a `exception.type`/`exception.message`.
|
|
57
|
+
# Default `true` durante la ventana de transición OTel v1.0. Setear a `false` cuando todos los
|
|
58
|
+
# consumers (dashboards, alertas, queries) hayan migrado a `exception.*` para reducir bytes
|
|
59
|
+
# y ruido en logs.
|
|
60
|
+
# Aplica a `ExisRay::LogSubscriber` (logs HTTP) y `ExisRay::TaskMonitor` (logs de tasks).
|
|
61
|
+
# @example false
|
|
62
|
+
attr_accessor :emit_legacy_exception_keys
|
|
63
|
+
|
|
64
|
+
# @!attribute [rw] emit_legacy_path_key
|
|
65
|
+
# @return [Boolean] Si true, `ExisRay::LogSubscriber` emite `path` (nombre legacy Wispro)
|
|
66
|
+
# junto a `url.path` (OTel v1.0). Default `true` durante la ventana de transición.
|
|
67
|
+
# Setear a `false` cuando los consumers (queries, dashboards, alertas) hayan migrado a
|
|
68
|
+
# `url.path` para reducir bytes y ruido en logs.
|
|
69
|
+
# Nota: `url.path` y `http_route` son semánticamente distintos (URL concreta vs template);
|
|
70
|
+
# coinciden como string solo en endpoints sin params — la dupe es esperada y no se elimina.
|
|
71
|
+
# @example false
|
|
72
|
+
attr_accessor :emit_legacy_path_key
|
|
73
|
+
|
|
55
74
|
# Inicializa la configuración con valores por defecto compatibles con AWS X-Ray.
|
|
56
75
|
def initialize
|
|
57
76
|
@trace_header = "HTTP_X_AMZN_TRACE_ID"
|
|
@@ -62,6 +81,8 @@ module ExisRay
|
|
|
62
81
|
@log_subscriber_class = nil
|
|
63
82
|
@service_version = default_service_version
|
|
64
83
|
@deployment_environment = default_deployment_environment
|
|
84
|
+
@emit_legacy_exception_keys = true
|
|
85
|
+
@emit_legacy_path_key = true
|
|
65
86
|
end
|
|
66
87
|
|
|
67
88
|
# Lee la versión del servicio desde la configuración de Rails.
|
|
@@ -98,7 +98,7 @@ module ExisRay
|
|
|
98
98
|
component: "exis_ray",
|
|
99
99
|
event: "http_request",
|
|
100
100
|
method: payload[:method],
|
|
101
|
-
path: payload[:path],
|
|
101
|
+
"url.path": payload[:path],
|
|
102
102
|
http_route: extract_http_route(payload),
|
|
103
103
|
format: payload[:format],
|
|
104
104
|
controller: payload[:controller],
|
|
@@ -112,6 +112,8 @@ module ExisRay
|
|
|
112
112
|
server_address: extract_server_address(headers["HTTP_HOST"])
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
+
data[:path] = payload[:path] if ExisRay.configuration.emit_legacy_path_key
|
|
116
|
+
|
|
115
117
|
data.merge!(exception_data)
|
|
116
118
|
data.merge!(self.class.extra_fields(event))
|
|
117
119
|
data.compact
|
|
@@ -129,15 +131,16 @@ module ExisRay
|
|
|
129
131
|
end
|
|
130
132
|
|
|
131
133
|
# Extrae los datos de excepción para logs OTel.
|
|
132
|
-
#
|
|
133
|
-
# (`
|
|
134
|
-
#
|
|
134
|
+
# Siempre emite `exception.type`/`exception.message`/`exception.stacktrace` (OTel v1.0).
|
|
135
|
+
# Emite además los campos legacy (`error_class`/`error_message`) cuando
|
|
136
|
+
# `ExisRay.configuration.emit_legacy_exception_keys` es `true` (default durante la
|
|
137
|
+
# ventana de transición). Setear a `false` cuando los consumers hayan migrado.
|
|
135
138
|
#
|
|
136
139
|
# El stacktrace se toma de `payload[:exception_object]` (expuesto por Rails), no
|
|
137
140
|
# de `payload[:exception]` que es solo `[class_name, message]`.
|
|
138
141
|
#
|
|
139
142
|
# @param payload [Hash] Payload completo del notification de Rails.
|
|
140
|
-
# @return [Hash] Campos exception.* y error_class/error_message
|
|
143
|
+
# @return [Hash] Campos exception.* (y error_class/error_message si el flag está activo).
|
|
141
144
|
def extract_exception_data(payload)
|
|
142
145
|
exception_info = payload[:exception]
|
|
143
146
|
return {} unless exception_info
|
|
@@ -146,12 +149,15 @@ module ExisRay
|
|
|
146
149
|
exception_message = exception_info.last
|
|
147
150
|
|
|
148
151
|
data = {
|
|
149
|
-
error_class: exception_class,
|
|
150
|
-
error_message: exception_message,
|
|
151
152
|
"exception.type": exception_class,
|
|
152
153
|
"exception.message": exception_message
|
|
153
154
|
}
|
|
154
155
|
|
|
156
|
+
if ExisRay.configuration.emit_legacy_exception_keys
|
|
157
|
+
data[:error_class] = exception_class
|
|
158
|
+
data[:error_message] = exception_message
|
|
159
|
+
end
|
|
160
|
+
|
|
155
161
|
exception_object = payload[:exception_object]
|
|
156
162
|
if exception_object.respond_to?(:backtrace) && exception_object.backtrace
|
|
157
163
|
data[:"exception.stacktrace"] = exception_object.backtrace.take(20).join("\n")
|
|
@@ -47,9 +47,7 @@ module ExisRay
|
|
|
47
47
|
log_event(:error,
|
|
48
48
|
"component=exis_ray event=task_finished " \
|
|
49
49
|
"outcome=failed duration_s=#{duration_s} duration_human=\"#{human_time}\" " \
|
|
50
|
-
"
|
|
51
|
-
"exception.type=#{e.class} exception.message=#{e.message.inspect} " \
|
|
52
|
-
"exception.stacktrace=#{format_stacktrace(e.backtrace)}")
|
|
50
|
+
"#{format_exception_fields(e)}")
|
|
53
51
|
raise e
|
|
54
52
|
ensure
|
|
55
53
|
# Limpieza centralizada obligatoria para evitar filtraciones de memoria o contexto
|
|
@@ -124,7 +122,26 @@ module ExisRay
|
|
|
124
122
|
'""'
|
|
125
123
|
end
|
|
126
124
|
|
|
125
|
+
# Construye los campos KV de excepción para el log de `task_finished` failed.
|
|
126
|
+
# Siempre incluye `exception.type` / `exception.message` / `exception.stacktrace` (OTel v1.0).
|
|
127
|
+
# Incluye además `error_class` / `error_message` cuando
|
|
128
|
+
# `ExisRay.configuration.emit_legacy_exception_keys` es `true` (default durante la ventana
|
|
129
|
+
# de transición).
|
|
130
|
+
#
|
|
131
|
+
# @param error [Exception]
|
|
132
|
+
# @return [String]
|
|
133
|
+
def self.format_exception_fields(error)
|
|
134
|
+
message_quoted = error.message.inspect
|
|
135
|
+
stack = format_stacktrace(error.backtrace)
|
|
136
|
+
|
|
137
|
+
parts = []
|
|
138
|
+
parts << "error_class=#{error.class} error_message=#{message_quoted}" if ExisRay.configuration.emit_legacy_exception_keys
|
|
139
|
+
parts << "exception.type=#{error.class} exception.message=#{message_quoted} " \
|
|
140
|
+
"exception.stacktrace=#{stack}"
|
|
141
|
+
parts.join(" ")
|
|
142
|
+
end
|
|
143
|
+
|
|
127
144
|
private_class_method :pod_identifier, :setup_tracer, :execute_with_optional_tags,
|
|
128
|
-
:log_event, :format_stacktrace
|
|
145
|
+
:log_event, :format_stacktrace, :format_exception_fields
|
|
129
146
|
end
|
|
130
147
|
end
|
data/lib/exis_ray/version.rb
CHANGED
data/skill/SKILL.md
CHANGED
|
@@ -80,7 +80,7 @@ ExisRay unifica trazabilidad distribuida, logging estructurado JSON, contexto de
|
|
|
80
80
|
3. `ExisRay.sync_correlation_id` asigna `Tracer.correlation_id` a `Current.correlation_id`
|
|
81
81
|
4. Controller ejecuta `before_action` para setear `Current.user_id`, `Current.isp_id`
|
|
82
82
|
5. `JsonFormatter` intercepta cada `Rails.logger.*` e inyecta el contexto de ejecucion en cada linea. **No es incondicional:** cada campo tiene un guard especifico (ver tabla "Condiciones de emision" mas abajo). En particular `inject_tracer_context` corta el bloque `root_id`/`trace_id`/`source`/`task`/`sidekiq_job` con `return unless Tracer.root_id` — la invariante "todo entrypoint garantiza `root_id`" es lo que hace que `source` (mandatorio) nunca falte. `request_id` se emite **fuera** de ese guard (distinto ciclo de vida que `root_id`). El developer aporta `component` (modulo de negocio) y `event` (que paso); estos NO son auto-inyectados porque dependen del call site, no del contexto de ejecucion.
|
|
83
|
-
6. `LogSubscriber` emite un unico Hash al finalizar el request con campos default (`component`, `event`, `method`, `path`, `http_route`, `format`, `controller`, `action`, `http_status`, `duration_s`, `duration_human`, `view_runtime_s`, `db_runtime_s`, `user_agent_original`, `server_address`, y en error `error_class`/`error_message
|
|
83
|
+
6. `LogSubscriber` emite un unico Hash al finalizar el request con campos default (`component`, `event`, `method`, `url.path` siempre + `path` si `config.emit_legacy_path_key`, `http_route`, `format`, `controller`, `action`, `http_status`, `duration_s`, `duration_human`, `view_runtime_s`, `db_runtime_s`, `user_agent_original`, `server_address`, y en error `exception.type`/`exception.message`/`exception.stacktrace` siempre + `error_class`/`error_message` si `config.emit_legacy_exception_keys`).
|
|
84
84
|
7. En llamadas salientes, `FaradayMiddleware`/`ActiveResourceInstrumentation` inyectan `propagation_trace_header` con `Tracer.generate_trace_header`
|
|
85
85
|
8. Al finalizar, `ActiveSupport::CurrentAttributes` hace reset automatico
|
|
86
86
|
|
|
@@ -100,6 +100,8 @@ ExisRay.configure do |config|
|
|
|
100
100
|
config.log_subscriber_class = "MyLogSubscriber" # String|nil, default nil
|
|
101
101
|
config.service_version = "1.2.3" # String|nil, default: Rails config.version o config.x.version
|
|
102
102
|
config.deployment_environment = "production" # String|nil, default: Rails.env
|
|
103
|
+
config.emit_legacy_exception_keys = true # Boolean, default true (ventana transicion OTel v1.0)
|
|
104
|
+
config.emit_legacy_path_key = true # Boolean, default true (ventana transicion `path` -> `url.path` OTel v1.0)
|
|
103
105
|
end
|
|
104
106
|
|
|
105
107
|
ExisRay.configuration.json_logs? # => true si log_format == :json
|
|
@@ -233,8 +235,9 @@ ExisRay::TaskMonitor.run("billing:generate_invoices") do
|
|
|
233
235
|
InvoiceService.process_all
|
|
234
236
|
end
|
|
235
237
|
# Genera root_id propio, loguea task_started/task_finished con outcome y duration_s.
|
|
236
|
-
# En caso de error emite:
|
|
237
|
-
#
|
|
238
|
+
# En caso de error emite: exception.type, exception.message, exception.stacktrace
|
|
239
|
+
# (OTel, limitado a 20 lineas) + error_class/error_message si
|
|
240
|
+
# config.emit_legacy_exception_keys es true (default durante ventana de transicion).
|
|
238
241
|
# Re-lanza excepciones despues de loguearlas.
|
|
239
242
|
# Hace reset de Tracer, Current y Reporter en ensure.
|
|
240
243
|
```
|
|
@@ -250,8 +253,9 @@ Reemplaza Lograge. Se suscribe a `process_action.action_controller` y emite un H
|
|
|
250
253
|
| `component` | String | Siempre `"exis_ray"` |
|
|
251
254
|
| `event` | String | Siempre `"http_request"` |
|
|
252
255
|
| `method` | String | Verbo HTTP |
|
|
253
|
-
| `path` | String | URL concreta del request |
|
|
254
|
-
| `
|
|
256
|
+
| `url.path` | String | URL concreta del request (OTel v1.0). Siempre presente |
|
|
257
|
+
| `path` | String | Alias legacy de `url.path`. Solo si `config.emit_legacy_path_key` (default `true`, deprecado) |
|
|
258
|
+
| `http_route` | String | Template (ej: `/users/:id`). Baja cardinalidad para dashboards. En endpoints sin params coincide en valor con `url.path` — dupe semanticamente esperada (concrete vs template) |
|
|
255
259
|
| `format` | Symbol/String | `html`, `json`, etc. |
|
|
256
260
|
| `controller` | String | Class name del controller |
|
|
257
261
|
| `action` | String | Nombre del action |
|
|
@@ -262,7 +266,7 @@ Reemplaza Lograge. Se suscribe a `process_action.action_controller` y emite un H
|
|
|
262
266
|
| `db_runtime_s` | Float\|nil | Solo si ActiveRecord lo reporta |
|
|
263
267
|
| `user_agent_original` | String | Header `User-Agent` |
|
|
264
268
|
| `server_address` | String | Hostname sin puerto (de `Host` header) |
|
|
265
|
-
| `error_class`, `error_message` | String | Solo en fallo (
|
|
269
|
+
| `error_class`, `error_message` | String | Solo en fallo y si `config.emit_legacy_exception_keys` (default `true`, deprecadas) |
|
|
266
270
|
| `exception.type`, `exception.message`, `exception.stacktrace` | String | Solo en fallo (OTel; stack limitado a 20 lineas) |
|
|
267
271
|
|
|
268
272
|
Para inyectar campos extra, sobreescribir `extra_fields`:
|
|
@@ -37,6 +37,14 @@ RSpec.describe ExisRay::Configuration do
|
|
|
37
37
|
it "deployment_environment por defecto es nil fuera de Rails" do
|
|
38
38
|
expect(config.deployment_environment).to be_nil
|
|
39
39
|
end
|
|
40
|
+
|
|
41
|
+
it "emit_legacy_exception_keys por defecto es true (ventana de transición OTel)" do
|
|
42
|
+
expect(config.emit_legacy_exception_keys).to be true
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "emit_legacy_path_key por defecto es true (ventana de transición OTel url.path)" do
|
|
46
|
+
expect(config.emit_legacy_path_key).to be true
|
|
47
|
+
end
|
|
40
48
|
end
|
|
41
49
|
|
|
42
50
|
describe "resource attributes OTel" do
|
|
@@ -158,5 +166,19 @@ RSpec.describe ExisRay::Configuration do
|
|
|
158
166
|
|
|
159
167
|
expect(config.log_subscriber_class).to eq("MyLogSubscriber")
|
|
160
168
|
end
|
|
169
|
+
|
|
170
|
+
it "permite cambiar emit_legacy_exception_keys" do
|
|
171
|
+
config = described_class.new
|
|
172
|
+
config.emit_legacy_exception_keys = false
|
|
173
|
+
|
|
174
|
+
expect(config.emit_legacy_exception_keys).to be false
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
it "permite cambiar emit_legacy_path_key" do
|
|
178
|
+
config = described_class.new
|
|
179
|
+
config.emit_legacy_path_key = false
|
|
180
|
+
|
|
181
|
+
expect(config.emit_legacy_path_key).to be false
|
|
182
|
+
end
|
|
161
183
|
end
|
|
162
184
|
end
|
|
@@ -151,6 +151,33 @@ RSpec.describe ExisRay::LogSubscriber do
|
|
|
151
151
|
expect(data[:server_address]).to eq("api.example.com")
|
|
152
152
|
end
|
|
153
153
|
|
|
154
|
+
it "emite url.path (OTel v1.0) siempre con la URL concreta" do
|
|
155
|
+
event = build_event(payload: base_payload)
|
|
156
|
+
|
|
157
|
+
data = subscriber.send(:build_payload, event)
|
|
158
|
+
|
|
159
|
+
expect(data[:"url.path"]).to eq("/users/42")
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
it "emite path (legacy Wispro) junto a url.path cuando emit_legacy_path_key=true (default)" do
|
|
163
|
+
event = build_event(payload: base_payload)
|
|
164
|
+
|
|
165
|
+
data = subscriber.send(:build_payload, event)
|
|
166
|
+
|
|
167
|
+
expect(data[:path]).to eq("/users/42")
|
|
168
|
+
expect(data[:"url.path"]).to eq("/users/42")
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
it "omite path cuando emit_legacy_path_key=false (solo url.path)" do
|
|
172
|
+
allow(ExisRay.configuration).to receive(:emit_legacy_path_key).and_return(false)
|
|
173
|
+
event = build_event(payload: base_payload)
|
|
174
|
+
|
|
175
|
+
data = subscriber.send(:build_payload, event)
|
|
176
|
+
|
|
177
|
+
expect(data).not_to have_key(:path)
|
|
178
|
+
expect(data[:"url.path"]).to eq("/users/42")
|
|
179
|
+
end
|
|
180
|
+
|
|
154
181
|
# Helper: construye un mock de ActionDispatch::Journey::Route con la API REAL
|
|
155
182
|
# que usa el código de producción (route.defaults, route.path.spec, route.verb).
|
|
156
183
|
# Esto evita el anti-patrón anterior de stubear una API inventada.
|
|
@@ -268,6 +295,22 @@ RSpec.describe ExisRay::LogSubscriber do
|
|
|
268
295
|
expect(data[:error_message]).to eq("something went wrong")
|
|
269
296
|
end
|
|
270
297
|
|
|
298
|
+
it "omite error_class/error_message cuando emit_legacy_exception_keys=false" do
|
|
299
|
+
allow(ExisRay.configuration).to receive(:emit_legacy_exception_keys).and_return(false)
|
|
300
|
+
|
|
301
|
+
event = build_event(payload: base_payload.merge(
|
|
302
|
+
status: nil,
|
|
303
|
+
exception: ["RuntimeError", "something went wrong"]
|
|
304
|
+
))
|
|
305
|
+
|
|
306
|
+
data = subscriber.send(:build_payload, event)
|
|
307
|
+
|
|
308
|
+
expect(data[:"exception.type"]).to eq("RuntimeError")
|
|
309
|
+
expect(data[:"exception.message"]).to eq("something went wrong")
|
|
310
|
+
expect(data).not_to have_key(:error_class)
|
|
311
|
+
expect(data).not_to have_key(:error_message)
|
|
312
|
+
end
|
|
313
|
+
|
|
271
314
|
it "inyecta exception.stacktrace desde payload[:exception_object]" do
|
|
272
315
|
exception_object = RuntimeError.new("boom")
|
|
273
316
|
exception_object.set_backtrace(["a.rb:1", "b.rb:2", "c.rb:3"])
|
|
@@ -109,6 +109,21 @@ RSpec.describe ExisRay::TaskMonitor do
|
|
|
109
109
|
expect(finish_log[1]).to include("exception.stacktrace=")
|
|
110
110
|
end
|
|
111
111
|
|
|
112
|
+
it "omite error_class/error_message cuando emit_legacy_exception_keys=false" do
|
|
113
|
+
allow(ExisRay.configuration).to receive(:emit_legacy_exception_keys).and_return(false)
|
|
114
|
+
|
|
115
|
+
expect do
|
|
116
|
+
described_class.run("task:boom") { raise "kaboom" }
|
|
117
|
+
end.to raise_error(RuntimeError, "kaboom")
|
|
118
|
+
|
|
119
|
+
finish_log = captured_logs.find { |lvl, msg| lvl == :error && msg.include?("task_finished") }
|
|
120
|
+
expect(finish_log[1]).not_to include("error_class=")
|
|
121
|
+
expect(finish_log[1]).not_to include("error_message=")
|
|
122
|
+
expect(finish_log[1]).to include("exception.type=RuntimeError")
|
|
123
|
+
expect(finish_log[1]).to include("exception.message=")
|
|
124
|
+
expect(finish_log[1]).to include("exception.stacktrace=")
|
|
125
|
+
end
|
|
126
|
+
|
|
112
127
|
it "resetea el Tracer incluso en caso de error" do
|
|
113
128
|
begin
|
|
114
129
|
described_class.run("task:boom") { raise "kaboom" }
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: exis_ray
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.11.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Gabriel Edera
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-05-
|
|
11
|
+
date: 2026-05-26 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -90,8 +90,8 @@ licenses:
|
|
|
90
90
|
metadata:
|
|
91
91
|
homepage_uri: https://github.com/gedera/exis_ray
|
|
92
92
|
source_code_uri: https://github.com/gedera/exis_ray
|
|
93
|
-
changelog_uri: https://github.com/gedera/exis_ray/blob/v0.
|
|
94
|
-
documentation_uri: https://github.com/gedera/exis_ray/blob/v0.
|
|
93
|
+
changelog_uri: https://github.com/gedera/exis_ray/blob/v0.11.0/CHANGELOG.md
|
|
94
|
+
documentation_uri: https://github.com/gedera/exis_ray/blob/v0.11.0/skill
|
|
95
95
|
post_install_message:
|
|
96
96
|
rdoc_options: []
|
|
97
97
|
require_paths:
|