exis_ray 0.4.0 → 0.4.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 +4 -4
- data/CHANGELOG.md +17 -0
- data/lib/exis_ray/json_formatter.rb +30 -2
- data/lib/exis_ray/log_subscriber.rb +8 -1
- data/lib/exis_ray/railtie.rb +9 -19
- data/lib/exis_ray/reporter.rb +1 -1
- data/lib/exis_ray/task_monitor.rb +5 -9
- data/lib/exis_ray/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ad3239a79f3c1393bc7138ed81a149afbc8564817687906e1dd06931a231a03f
|
|
4
|
+
data.tar.gz: 5ff151e3ca3035d9d962622ea9a5b3231078fe913be160d1acb1e8f1c892f05e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 333e04eb54ce9df129976069e99bd349d4c56902e0f1c2e39baa56fc15bcdfacea9b977bb4e03f35bad36d0cf3ad149aa232c8de90385f267d035b24af666fc4
|
|
7
|
+
data.tar.gz: 1cb26ee1550c63524352ecce48ce2fcc761076cf9f6957757ce0e14b9ab6ced7aadc09e45ac0a954f8c2dc1018555f446ed1aa0fc9f2d3e44d6e7722c8d5e3a9
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
## [0.4.2] - 2026-03-23
|
|
2
|
+
|
|
3
|
+
### Added
|
|
4
|
+
- **Full compliance with "Gabriel's Global Standards" for Logging:**
|
|
5
|
+
- **Sensitive Data Filtering:** The KV parser and Hash merger now automatically filter sensitive keys (`password`, `token`, `api_key`, `auth`, etc.) replacing values with `[FILTERED]`.
|
|
6
|
+
- **Standardized HTTP Logs:** Added `component=exis_ray` and `event=http_request` to all automatic Rails request logs.
|
|
7
|
+
- **Dynamic Log Levels:** `LogSubscriber` now uses `ERROR` level for 5xx status codes and `INFO` for the rest.
|
|
8
|
+
- **Performance:** Switched to block form for internal `DEBUG` logs in `Railtie` to avoid unnecessary string interpolation.
|
|
9
|
+
|
|
10
|
+
## [0.4.1] - 2026-03-23
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
- **Data-Driven Internal Logging:** Refactored internal library logs (boot, instrumentation, task status) from plain text messages to structured Key-Value (KV) strings.
|
|
14
|
+
- This leverages the `JsonFormatter`'s KV parser to elevate fields like `component`, `event`, and `status` to the JSON root, eliminating the need for unstructured `message` fields in infrastructure logs.
|
|
15
|
+
- Simplified `TaskMonitor#log_event` and `Railtie.log_boot` to emit raw KV strings directly to the logger.
|
|
16
|
+
- **Improved local debugging:** The `Reporter` now uses `exception.full_message` in non-production environments to provide a more readable backtrace in the development console.
|
|
17
|
+
|
|
1
18
|
## [0.4.0] - 2026-03-23
|
|
2
19
|
|
|
3
20
|
### Breaking Changes
|
|
@@ -25,6 +25,9 @@ module ExisRay
|
|
|
25
25
|
# Extrae pares key=value de un string. Soporta valores sin espacios o entre comillas dobles.
|
|
26
26
|
KV_PARSE_RE = /(\w+)=("(?:[^"\\]|\\.)*"|\S+)/
|
|
27
27
|
|
|
28
|
+
# Claves sensibles que deben filtrarse automáticamente según el estándar de Gabriel.
|
|
29
|
+
SENSITIVE_KEYS = /password|pass|passwd|secret|token|api_key|auth/i
|
|
30
|
+
|
|
28
31
|
# Procesa un mensaje de log y lo formatea como una cadena estructurada en JSON.
|
|
29
32
|
#
|
|
30
33
|
# @param severity [String] El nivel de severidad del log (ej. "INFO", "ERROR", "DEBUG").
|
|
@@ -103,7 +106,8 @@ module ExisRay
|
|
|
103
106
|
# @return [void]
|
|
104
107
|
def process_message(payload, msg)
|
|
105
108
|
if msg.is_a?(Hash)
|
|
106
|
-
|
|
109
|
+
# Filtramos las claves del Hash antes del merge
|
|
110
|
+
payload.merge!(filter_sensitive_hash(msg))
|
|
107
111
|
elsif msg.is_a?(String) && kv_string?(msg)
|
|
108
112
|
parsed = parse_kv_string(msg)
|
|
109
113
|
parsed.empty? ? payload[:message] = msg : payload.merge!(parsed)
|
|
@@ -129,9 +133,33 @@ module ExisRay
|
|
|
129
133
|
def parse_kv_string(str)
|
|
130
134
|
result = {}
|
|
131
135
|
str.scan(KV_PARSE_RE) do |key, value|
|
|
132
|
-
|
|
136
|
+
val = value.start_with?('"') ? (value[1..-2] || "").gsub('\\"', '"') : value
|
|
137
|
+
result[key.to_sym] = filter_sensitive_value(key, val)
|
|
133
138
|
end
|
|
134
139
|
result
|
|
135
140
|
end
|
|
141
|
+
|
|
142
|
+
# Filtra un valor si la clave se considera sensible.
|
|
143
|
+
#
|
|
144
|
+
# @param key [String, Symbol]
|
|
145
|
+
# @param value [Object]
|
|
146
|
+
# @return [Object]
|
|
147
|
+
def filter_sensitive_value(key, value)
|
|
148
|
+
key.to_s.match?(SENSITIVE_KEYS) ? "[FILTERED]" : value
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# Filtra recursivamente un Hash que contenga claves sensibles.
|
|
152
|
+
#
|
|
153
|
+
# @param hash [Hash]
|
|
154
|
+
# @return [Hash]
|
|
155
|
+
def filter_sensitive_hash(hash)
|
|
156
|
+
hash.each_with_object({}) do |(k, v), result|
|
|
157
|
+
result[k] = if v.is_a?(Hash)
|
|
158
|
+
filter_sensitive_hash(v)
|
|
159
|
+
else
|
|
160
|
+
filter_sensitive_value(k, v)
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
|
136
164
|
end
|
|
137
165
|
end
|
|
@@ -32,7 +32,12 @@ module ExisRay
|
|
|
32
32
|
# @return [void]
|
|
33
33
|
def process_action(event)
|
|
34
34
|
payload = build_payload(event)
|
|
35
|
-
|
|
35
|
+
# Usamos el nivel ERROR si el status es 5xx, cumpliendo el estándar de Gabriel.
|
|
36
|
+
if payload[:status] && payload[:status] >= 500
|
|
37
|
+
logger.error(payload)
|
|
38
|
+
else
|
|
39
|
+
logger.info(payload)
|
|
40
|
+
end
|
|
36
41
|
rescue StandardError
|
|
37
42
|
# El logger nunca debe interrumpir el flujo del request.
|
|
38
43
|
end
|
|
@@ -65,6 +70,8 @@ module ExisRay
|
|
|
65
70
|
status = payload[:status] || exception_status(payload[:exception])
|
|
66
71
|
|
|
67
72
|
data = {
|
|
73
|
+
component: "exis_ray",
|
|
74
|
+
event: "http_request",
|
|
68
75
|
method: payload[:method],
|
|
69
76
|
path: payload[:path],
|
|
70
77
|
format: payload[:format],
|
data/lib/exis_ray/railtie.rb
CHANGED
|
@@ -41,18 +41,14 @@ module ExisRay
|
|
|
41
41
|
require "exis_ray/log_subscriber"
|
|
42
42
|
ExisRay::LogSubscriber.install!
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
log_boot("component=exis_ray event=json_logging_enabled")
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
# --- Instrumentación de ActiveResource ---
|
|
48
48
|
if defined?(ActiveResource::Base)
|
|
49
49
|
require "exis_ray/active_resource_instrumentation"
|
|
50
50
|
ActiveResource::Base.send(:prepend, ExisRay::ActiveResourceInstrumentation)
|
|
51
|
-
|
|
52
|
-
log_message(
|
|
53
|
-
text: "[ExisRay] ActiveResource instrumentado.",
|
|
54
|
-
json: { message: "[ExisRay] ActiveResource instrumentado." }
|
|
55
|
-
)
|
|
51
|
+
log_boot("component=exis_ray event=active_resource_instrumented")
|
|
56
52
|
end
|
|
57
53
|
|
|
58
54
|
# --- Instrumentación de Sidekiq ---
|
|
@@ -75,27 +71,21 @@ module ExisRay
|
|
|
75
71
|
end
|
|
76
72
|
end
|
|
77
73
|
|
|
78
|
-
# Sidekiq maneja su propio logger. Lo forzamos a usar nuestra estructura JSON.
|
|
79
74
|
if ExisRay.configuration.json_logs? && ::Sidekiq.logger
|
|
80
75
|
::Sidekiq.logger.formatter = ExisRay::JsonFormatter.new
|
|
81
|
-
Rails.logger.info({ message: "[ExisRay] Sidekiq Middleware y JsonFormatter integrados." })
|
|
82
|
-
else
|
|
83
|
-
Rails.logger.info "[ExisRay] Sidekiq Middleware integrado."
|
|
84
76
|
end
|
|
77
|
+
log_boot("component=exis_ray event=sidekiq_instrumented")
|
|
85
78
|
end
|
|
86
79
|
end
|
|
87
80
|
|
|
88
|
-
#
|
|
81
|
+
# Emite un log de boot en DEBUG con formato key=value.
|
|
82
|
+
# En modo texto es legible directamente. En modo JSON el JsonFormatter
|
|
83
|
+
# lo parsea y eleva cada campo al nivel raíz del JSON automáticamente.
|
|
89
84
|
#
|
|
90
|
-
# @param
|
|
91
|
-
# @param json [Hash] El payload para el formato JSON.
|
|
85
|
+
# @param message [String] String en formato key=value.
|
|
92
86
|
# @return [void]
|
|
93
|
-
def self.
|
|
94
|
-
|
|
95
|
-
Rails.logger.info(json)
|
|
96
|
-
else
|
|
97
|
-
Rails.logger.info(text)
|
|
98
|
-
end
|
|
87
|
+
def self.log_boot(message)
|
|
88
|
+
Rails.logger.debug { message }
|
|
99
89
|
end
|
|
100
90
|
end
|
|
101
91
|
end
|
data/lib/exis_ray/reporter.rb
CHANGED
|
@@ -32,7 +32,7 @@ module ExisRay
|
|
|
32
32
|
prepare_scope(context, tags, fingerprint, transaction_name)
|
|
33
33
|
add_tags(exception: excep.class.to_s)
|
|
34
34
|
|
|
35
|
-
Rails.logger.error(excep) unless Rails.env.production?
|
|
35
|
+
Rails.logger.error(excep.full_message) unless Rails.env.production?
|
|
36
36
|
|
|
37
37
|
if report_to_new_sentry?
|
|
38
38
|
exception_to_new_sentry(excep)
|
|
@@ -29,14 +29,14 @@ module ExisRay
|
|
|
29
29
|
curr.correlation_id = ExisRay::Tracer.correlation_id
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
-
log_event(:info, "
|
|
32
|
+
log_event(:info, "component=exis_ray event=task_started task=#{task_name} status=started")
|
|
33
33
|
|
|
34
34
|
# Bloque de ejecución con o sin tags dependiendo de la configuración
|
|
35
35
|
execute_with_optional_tags { yield }
|
|
36
36
|
|
|
37
|
-
log_event(:info, "
|
|
37
|
+
log_event(:info, "component=exis_ray event=task_finished task=#{task_name} status=success")
|
|
38
38
|
rescue StandardError => e
|
|
39
|
-
log_event(:error, "
|
|
39
|
+
log_event(:error, "component=exis_ray event=task_failed task=#{task_name} status=failed error=#{e.message.inspect}")
|
|
40
40
|
raise e
|
|
41
41
|
ensure
|
|
42
42
|
# Limpieza centralizada obligatoria para evitar filtraciones de memoria o contexto
|
|
@@ -89,12 +89,8 @@ module ExisRay
|
|
|
89
89
|
# @param message [String] Mensaje en texto plano para el modo clásico.
|
|
90
90
|
# @param payload [Hash] Datos estructurados para el modo JSON.
|
|
91
91
|
# @return [void]
|
|
92
|
-
def self.log_event(level, message
|
|
93
|
-
|
|
94
|
-
Rails.logger.send(level, payload.merge(message: "[ExisRay] #{message}"))
|
|
95
|
-
else
|
|
96
|
-
Rails.logger.send(level, "[ExisRay] #{message}")
|
|
97
|
-
end
|
|
92
|
+
def self.log_event(level, message)
|
|
93
|
+
Rails.logger.send(level, message)
|
|
98
94
|
rescue StandardError
|
|
99
95
|
# El logger nunca debe interrumpir el flujo principal de la tarea.
|
|
100
96
|
end
|
data/lib/exis_ray/version.rb
CHANGED