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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c5162f50fce688356ff17e9adff2464f6bc7ba9c83ee2e3a1f662dc4568fb6d3
4
- data.tar.gz: b2559412f57a487971edbf42cd0b24e18bbbe9fe33890096e8e6769647895e49
3
+ metadata.gz: ad3239a79f3c1393bc7138ed81a149afbc8564817687906e1dd06931a231a03f
4
+ data.tar.gz: 5ff151e3ca3035d9d962622ea9a5b3231078fe913be160d1acb1e8f1c892f05e
5
5
  SHA512:
6
- metadata.gz: 9efba79f9584005d1beb8c1d749dc4efb54959aa47433a671b611cbc15ce93bb4f081f390047b736039a1fad1d621cc2d5661fb82c3f340c2f57a7bddc461f19
7
- data.tar.gz: a2878c45410719109283a4a2b44201bc0b45fbe5a7ee2c70ba020a5b255392ab42af18fa52995f75e98dc4e32ae0727c718429b590daa3af797202e1488db897
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
- payload.merge!(msg)
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
- result[key.to_sym] = value.start_with?('"') ? (value[1..-2] || "").gsub('\\"', '"') : value
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
- logger.info(payload)
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],
@@ -41,18 +41,14 @@ module ExisRay
41
41
  require "exis_ray/log_subscriber"
42
42
  ExisRay::LogSubscriber.install!
43
43
 
44
- Rails.logger.info({ message: "[ExisRay] JSON Logging unificado activado." })
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
- # Helper interno para imprimir logs de inicialización respetando el formato elegido.
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 text [String] El mensaje para el formato texto.
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.log_message(text:, json:)
94
- if ExisRay.configuration.json_logs?
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
@@ -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, "Iniciando tarea: #{task_name}", task: task_name, status: "started")
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, "Finalizada con éxito.", task: task_name, status: "success")
37
+ log_event(:info, "component=exis_ray event=task_finished task=#{task_name} status=success")
38
38
  rescue StandardError => e
39
- log_event(:error, "Falló la tarea #{task_name}: #{e.message}", task: task_name, status: "failed", error: e.message)
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, **payload)
93
- if ExisRay.configuration.json_logs?
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
@@ -2,5 +2,5 @@
2
2
 
3
3
  module ExisRay
4
4
  # Versión actual de la gema.
5
- VERSION = "0.4.0"
5
+ VERSION = "0.4.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.4.0
4
+ version: 0.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gabriel Edera