chronos-ruby 0.3.0.pre.1 → 0.5.0.pre.1
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 +23 -0
- data/README.md +55 -17
- data/contracts/event-v1.schema.json +25 -11
- data/contracts/rack-context-v1.schema.json +43 -0
- data/docs/adr/ADR-012-rack-context-isolation.md +27 -0
- data/docs/adr/ADR-013-legacy-rails-notifications.md +27 -0
- data/docs/architecture.md +17 -3
- data/docs/compatibility.md +6 -6
- data/docs/configuration.md +13 -2
- data/docs/data-collected.md +15 -2
- data/docs/modules/rack-context.md +59 -0
- data/docs/modules/rails-legacy.md +60 -0
- data/docs/modules/telemetry-events.md +9 -0
- data/docs/performance.md +28 -3
- data/docs/privacy-lgpd.md +13 -3
- data/docs/troubleshooting.md +18 -2
- data/lib/chronos/adapters/thread_local_context_store.rb +52 -0
- data/lib/chronos/agent.rb +97 -6
- data/lib/chronos/application/capture_exception.rb +2 -2
- data/lib/chronos/application/capture_telemetry.rb +37 -0
- data/lib/chronos/application/remote_configuration.rb +1 -1
- data/lib/chronos/configuration/snapshot.rb +53 -0
- data/lib/chronos/configuration/validation.rb +122 -0
- data/lib/chronos/configuration.rb +22 -134
- data/lib/chronos/core/breadcrumb.rb +126 -0
- data/lib/chronos/core/telemetry_event.rb +106 -0
- data/lib/chronos/integrations/rack/middleware.rb +156 -0
- data/lib/chronos/integrations/rack.rb +12 -0
- data/lib/chronos/integrations.rb +10 -0
- data/lib/chronos/ports/context_store.rb +22 -0
- data/lib/chronos/rails/installer.rb +70 -0
- data/lib/chronos/rails/notifications_subscriber.rb +203 -0
- data/lib/chronos/rails/railtie.rb +21 -0
- data/lib/chronos/rails.rb +16 -0
- data/lib/chronos/version.rb +1 -1
- data/lib/chronos.rb +46 -1
- data/lib/generators/chronos/install/install_generator.rb +25 -0
- data/lib/generators/chronos/install/templates/chronos.rb +20 -0
- metadata +23 -1
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
module Chronos
|
|
2
|
+
module Rails
|
|
3
|
+
# Installs Rails middleware and subscribers exactly once per application.
|
|
4
|
+
#
|
|
5
|
+
# @responsibility Apply feature-detected integration hooks after Rails initializers load.
|
|
6
|
+
# @motivation Centralize version-neutral installation outside Railtie DSL code.
|
|
7
|
+
# @limits It does not configure credentials or depend on private Rails APIs.
|
|
8
|
+
# @collaborators Rails application middleware, NotificationsSubscriber, and Chronos facade.
|
|
9
|
+
# @thread_safety A mutex protects the per-application installation registry.
|
|
10
|
+
# @compatibility Rails 4.2 through Rails 5.2 without Zeitwerk.
|
|
11
|
+
# @example
|
|
12
|
+
# Chronos::Rails::Installer.new.install(Rails.application)
|
|
13
|
+
# @errors Missing optional Rails capabilities return false without affecting boot.
|
|
14
|
+
# @performance Installation is one-time; request work is delegated to bounded integrations.
|
|
15
|
+
class Installer
|
|
16
|
+
@mutex = Mutex.new
|
|
17
|
+
@applications = {}
|
|
18
|
+
|
|
19
|
+
class << self
|
|
20
|
+
attr_reader :mutex, :applications
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def initialize(notifier = Chronos, subscriber = nil)
|
|
24
|
+
@notifier = notifier
|
|
25
|
+
@subscriber = subscriber || NotificationsSubscriber.new(notifier)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def install(application)
|
|
29
|
+
options = @notifier.rails_integration_options(environment, console?)
|
|
30
|
+
return false unless options[:enabled]
|
|
31
|
+
|
|
32
|
+
self.class.mutex.synchronize do
|
|
33
|
+
return false if self.class.applications[application.object_id]
|
|
34
|
+
|
|
35
|
+
install_middleware(application, options)
|
|
36
|
+
@subscriber.install
|
|
37
|
+
self.class.applications[application.object_id] = true
|
|
38
|
+
end
|
|
39
|
+
true
|
|
40
|
+
rescue StandardError
|
|
41
|
+
false
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def rails_version
|
|
45
|
+
defined?(::Rails) && ::Rails.respond_to?(:version) ? ::Rails.version.to_s : "unknown"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def install_middleware(application, options)
|
|
51
|
+
middleware = application.config.middleware
|
|
52
|
+
return false unless middleware.respond_to?(:use)
|
|
53
|
+
|
|
54
|
+
middleware.use(
|
|
55
|
+
Chronos::Integrations::Rack::Middleware,
|
|
56
|
+
:include_user_agent => options[:include_user_agent]
|
|
57
|
+
)
|
|
58
|
+
true
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def environment
|
|
62
|
+
defined?(::Rails) && ::Rails.respond_to?(:env) ? ::Rails.env.to_s : nil
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def console?
|
|
66
|
+
defined?(::Rails::Console)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
module Chronos
|
|
2
|
+
module Rails
|
|
3
|
+
# Converts public ActiveSupport notifications into bounded Chronos telemetry.
|
|
4
|
+
#
|
|
5
|
+
# @responsibility Subscribe once and normalize controller, view, SQL, mailer, job, and cache events.
|
|
6
|
+
# @motivation Support Rails 4.2 and 5.2 through feature detection and public notification APIs.
|
|
7
|
+
# @limits It never sends SQL text, bind values, cache keys, mail bodies, or job arguments.
|
|
8
|
+
# @collaborators ActiveSupport::Notifications and the Chronos facade.
|
|
9
|
+
# @thread_safety Subscription registry is mutex-protected; callbacks own their state.
|
|
10
|
+
# @compatibility ActiveSupport notification argument shapes from Rails 4.2 through 5.2.
|
|
11
|
+
# @example
|
|
12
|
+
# Chronos::Rails::NotificationsSubscriber.new.install
|
|
13
|
+
# @errors Subscriber failures are contained and never escape into Rails.
|
|
14
|
+
# @performance Each notification builds a small allowlisted hash and queues asynchronously.
|
|
15
|
+
class NotificationsSubscriber
|
|
16
|
+
EVENTS = %w(
|
|
17
|
+
process_action.action_controller render_template.action_view sql.active_record
|
|
18
|
+
deliver.action_mailer perform.active_job cache_read.active_support
|
|
19
|
+
cache_write.active_support cache_fetch_hit.active_support
|
|
20
|
+
).freeze
|
|
21
|
+
|
|
22
|
+
@mutex = Mutex.new
|
|
23
|
+
@installed_buses = {}
|
|
24
|
+
|
|
25
|
+
class << self
|
|
26
|
+
attr_reader :mutex, :installed_buses
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def initialize(notifier = Chronos, notifications = nil)
|
|
30
|
+
@notifier = notifier
|
|
31
|
+
@notifications = notifications || active_support_notifications
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def install
|
|
35
|
+
return false unless @notifications && @notifications.respond_to?(:subscribe)
|
|
36
|
+
|
|
37
|
+
self.class.mutex.synchronize do
|
|
38
|
+
return false if self.class.installed_buses[@notifications.object_id]
|
|
39
|
+
|
|
40
|
+
event_names.each { |name| subscribe(name) }
|
|
41
|
+
self.class.installed_buses[@notifications.object_id] = true
|
|
42
|
+
end
|
|
43
|
+
true
|
|
44
|
+
rescue StandardError
|
|
45
|
+
false
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def handle(name, arguments)
|
|
49
|
+
event = notification_event(name, arguments)
|
|
50
|
+
dispatch(name, event[:payload], event[:duration_ms])
|
|
51
|
+
rescue StandardError
|
|
52
|
+
false
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
private
|
|
56
|
+
|
|
57
|
+
def active_support_notifications
|
|
58
|
+
return nil unless defined?(::ActiveSupport::Notifications)
|
|
59
|
+
|
|
60
|
+
::ActiveSupport::Notifications
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def subscribe(name)
|
|
64
|
+
@notifications.subscribe(name) { |*arguments| handle(name, arguments) }
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def event_names
|
|
68
|
+
return EVENTS if defined?(::ActiveJob)
|
|
69
|
+
|
|
70
|
+
EVENTS.reject { |name| name == "perform.active_job" }
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def notification_event(name, arguments)
|
|
74
|
+
candidate = arguments.first
|
|
75
|
+
if arguments.length == 1 && candidate.respond_to?(:payload)
|
|
76
|
+
return {:payload => hash(candidate.payload), :duration_ms => candidate.duration.to_f}
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
started_at = arguments[1]
|
|
80
|
+
finished_at = arguments[2]
|
|
81
|
+
{
|
|
82
|
+
:payload => hash(arguments[4]),
|
|
83
|
+
:duration_ms => duration_ms(started_at, finished_at),
|
|
84
|
+
:name => name
|
|
85
|
+
}
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def dispatch(name, payload, duration)
|
|
89
|
+
case name
|
|
90
|
+
when "process_action.action_controller" then process_action(payload, duration)
|
|
91
|
+
when "render_template.action_view" then render_template(payload, duration)
|
|
92
|
+
when "sql.active_record" then sql(payload, duration)
|
|
93
|
+
when "deliver.action_mailer" then mailer(payload, duration)
|
|
94
|
+
when "perform.active_job" then active_job(payload, duration)
|
|
95
|
+
else cache(name, payload, duration)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def process_action(payload, duration)
|
|
100
|
+
capture_controller_exception(payload)
|
|
101
|
+
data = {
|
|
102
|
+
"kind" => "controller", "controller" => value(payload, :controller),
|
|
103
|
+
"action" => value(payload, :action), "status" => value(payload, :status).to_i,
|
|
104
|
+
"method" => value(payload, :method), "path" => query_free_path(value(payload, :path)),
|
|
105
|
+
"route" => route(payload),
|
|
106
|
+
"duration_ms" => duration, "parameters" => hash(value(payload, :params))
|
|
107
|
+
}
|
|
108
|
+
@notifier.record_event("request", data)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def render_template(payload, duration)
|
|
112
|
+
data = {
|
|
113
|
+
"kind" => "view", "template" => safe_basename(value(payload, :identifier)),
|
|
114
|
+
"duration_ms" => duration
|
|
115
|
+
}
|
|
116
|
+
@notifier.record_event("request", data)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def sql(payload, duration)
|
|
120
|
+
data = {
|
|
121
|
+
"name" => value(payload, :name).to_s, "cached" => value(payload, :cached) == true,
|
|
122
|
+
"duration_ms" => duration
|
|
123
|
+
}
|
|
124
|
+
@notifier.record_event("query", data)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def mailer(payload, duration)
|
|
128
|
+
data = {
|
|
129
|
+
"kind" => "mailer", "mailer" => value(payload, :mailer).to_s,
|
|
130
|
+
"action" => value(payload, :action).to_s, "duration_ms" => duration
|
|
131
|
+
}
|
|
132
|
+
@notifier.record_event("job", data)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def active_job(payload, duration)
|
|
136
|
+
job = value(payload, :job)
|
|
137
|
+
data = {
|
|
138
|
+
"kind" => "active_job", "class" => safe_class_name(job),
|
|
139
|
+
"queue" => safe_job_value(job, :queue_name), "duration_ms" => duration
|
|
140
|
+
}
|
|
141
|
+
@notifier.record_event("job", data)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def cache(name, payload, duration)
|
|
145
|
+
data = {
|
|
146
|
+
"operation" => name.split(".").first, "store" => value(payload, :store).to_s,
|
|
147
|
+
"hit" => value(payload, :hit), "duration_ms" => duration
|
|
148
|
+
}
|
|
149
|
+
@notifier.record_event("cache", data)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def capture_controller_exception(payload)
|
|
153
|
+
exception = value(payload, :exception_object)
|
|
154
|
+
details = value(payload, :exception)
|
|
155
|
+
exception ||= RuntimeError.new(Array(details).last.to_s) if details
|
|
156
|
+
@notifier.notify_once(exception, :parameters => hash(value(payload, :params))) if exception
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def value(payload, key)
|
|
160
|
+
payload.key?(key) ? payload[key] : payload[key.to_s]
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def hash(value)
|
|
164
|
+
value.is_a?(Hash) ? value : {}
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def duration_ms(started_at, finished_at)
|
|
168
|
+
return 0.0 unless started_at && finished_at
|
|
169
|
+
|
|
170
|
+
((finished_at.to_f - started_at.to_f) * 1000.0).round(3)
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def query_free_path(path)
|
|
174
|
+
path.to_s.split("?", 2).first
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def route(payload)
|
|
178
|
+
explicit = value(payload, :route)
|
|
179
|
+
return explicit.to_s unless explicit.to_s.empty?
|
|
180
|
+
|
|
181
|
+
[value(payload, :controller), value(payload, :action)].compact.join("#")
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def safe_basename(identifier)
|
|
185
|
+
File.basename(identifier.to_s)
|
|
186
|
+
rescue StandardError
|
|
187
|
+
"<template>"
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def safe_class_name(object)
|
|
191
|
+
object ? object.class.name.to_s : ""
|
|
192
|
+
rescue StandardError
|
|
193
|
+
"Object"
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def safe_job_value(job, method_name)
|
|
197
|
+
job.respond_to?(method_name) ? job.public_send(method_name).to_s : ""
|
|
198
|
+
rescue StandardError
|
|
199
|
+
""
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Chronos
|
|
2
|
+
module Rails
|
|
3
|
+
# Hooks Chronos installation into the public Rails initializer lifecycle.
|
|
4
|
+
#
|
|
5
|
+
# @responsibility Install integrations after application configuration initializers load.
|
|
6
|
+
# @motivation Ensure generated Chronos configuration exists before hooks are activated.
|
|
7
|
+
# @limits It performs no autoloading and does not use private Rails initialization APIs.
|
|
8
|
+
# @collaborators Rails::Railtie and Chronos::Rails::Installer.
|
|
9
|
+
# @thread_safety Rails invokes the initializer during serialized application boot.
|
|
10
|
+
# @compatibility Rails 4.2 through Rails 5.2; no Zeitwerk requirement.
|
|
11
|
+
# @example
|
|
12
|
+
# require "chronos/rails"
|
|
13
|
+
# @errors Installer contains optional integration failures and allows Rails to boot.
|
|
14
|
+
# @performance Adds only one initializer and one-time installation work.
|
|
15
|
+
class Railtie < ::Rails::Railtie
|
|
16
|
+
initializer "chronos.install", :after => :load_config_initializers do |application|
|
|
17
|
+
Chronos::Rails::Installer.new.install(application)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require "chronos"
|
|
2
|
+
require "chronos/rails/notifications_subscriber"
|
|
3
|
+
require "chronos/rails/installer"
|
|
4
|
+
|
|
5
|
+
require "chronos/rails/railtie" if defined?(::Rails::Railtie)
|
|
6
|
+
|
|
7
|
+
module Chronos
|
|
8
|
+
# Legacy Rails integration loaded explicitly after Rails is available.
|
|
9
|
+
#
|
|
10
|
+
# @responsibility Namespace Railtie, installer, and notification subscribers.
|
|
11
|
+
# @motivation Keep Rails and ActiveSupport out of the framework-independent core.
|
|
12
|
+
# @limits Version 0.5 targets public APIs present in Rails 4.2 and 5.2.
|
|
13
|
+
# @thread_safety Installation and subscriptions are protected against duplication.
|
|
14
|
+
# @compatibility Rails 4.2 through Rails 5.2 with their supported legacy Rubies.
|
|
15
|
+
module Rails; end
|
|
16
|
+
end
|
data/lib/chronos/version.rb
CHANGED
data/lib/chronos.rb
CHANGED
|
@@ -15,24 +15,32 @@ require "chronos/core/sensitive_value_filter"
|
|
|
15
15
|
require "chronos/core/sanitizer"
|
|
16
16
|
require "chronos/core/safe_serializer"
|
|
17
17
|
require "chronos/core/payload_serializer"
|
|
18
|
+
require "chronos/core/telemetry_event"
|
|
18
19
|
require "chronos/ports/transport"
|
|
20
|
+
require "chronos/ports/context_store"
|
|
19
21
|
require "chronos/internal/safe_logger"
|
|
20
22
|
require "chronos/internal/bounded_queue"
|
|
21
23
|
require "chronos/internal/memory_backlog"
|
|
22
24
|
require "chronos/internal/worker_pool"
|
|
23
25
|
require "chronos/adapters/net_http_transport"
|
|
26
|
+
require "chronos/adapters/thread_local_context_store"
|
|
27
|
+
require "chronos/core/breadcrumb"
|
|
24
28
|
require "chronos/application/retry_policy"
|
|
25
29
|
require "chronos/application/circuit_breaker"
|
|
26
30
|
require "chronos/application/remote_configuration"
|
|
27
31
|
require "chronos/application/delivery_pipeline"
|
|
28
32
|
require "chronos/application/capture_exception"
|
|
33
|
+
require "chronos/application/capture_telemetry"
|
|
29
34
|
require "chronos/agent"
|
|
35
|
+
require "chronos/integrations"
|
|
36
|
+
require "chronos/integrations/rack"
|
|
37
|
+
require "chronos/integrations/rack/middleware"
|
|
30
38
|
|
|
31
39
|
# Framework-independent public facade for the Chronos Ruby agent.
|
|
32
40
|
#
|
|
33
41
|
# @responsibility Configure the agent and expose its small lifecycle API.
|
|
34
42
|
# @motivation Give applications a stable entry point while internals evolve.
|
|
35
|
-
# @limits
|
|
43
|
+
# @limits Rails integration remains optional and must be loaded through chronos/rails.
|
|
36
44
|
# @collaborators Configuration and Agent.
|
|
37
45
|
# @thread_safety Agent replacement and lookup are protected by a mutex.
|
|
38
46
|
# @compatibility Ruby 2.2.10 through Ruby 2.6.
|
|
@@ -75,6 +83,41 @@ module Chronos
|
|
|
75
83
|
false
|
|
76
84
|
end
|
|
77
85
|
|
|
86
|
+
def with_context(context = {})
|
|
87
|
+
agent = current_agent
|
|
88
|
+
return yield unless agent
|
|
89
|
+
|
|
90
|
+
agent.with_context(context) { yield }
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def add_breadcrumb(attributes = {})
|
|
94
|
+
agent = current_agent
|
|
95
|
+
agent ? agent.add_breadcrumb(attributes) : false
|
|
96
|
+
rescue StandardError
|
|
97
|
+
false
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def record_event(event_type, payload = {}, context = {})
|
|
101
|
+
agent = current_agent
|
|
102
|
+
agent ? agent.record_event(event_type, payload, context) : false
|
|
103
|
+
rescue StandardError
|
|
104
|
+
false
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def notify_once(exception, context = {})
|
|
108
|
+
agent = current_agent
|
|
109
|
+
agent ? agent.notify_once(exception, context) : false
|
|
110
|
+
rescue StandardError
|
|
111
|
+
false
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def rails_integration_options(environment = nil, console = false)
|
|
115
|
+
agent = current_agent
|
|
116
|
+
agent ? agent.rails_integration_options(environment, console) : {:enabled => false}
|
|
117
|
+
rescue StandardError
|
|
118
|
+
{:enabled => false}
|
|
119
|
+
end
|
|
120
|
+
|
|
78
121
|
def configured?
|
|
79
122
|
!current_agent.nil?
|
|
80
123
|
end
|
|
@@ -104,3 +147,5 @@ module Chronos
|
|
|
104
147
|
end
|
|
105
148
|
end
|
|
106
149
|
end
|
|
150
|
+
|
|
151
|
+
require "chronos/rails" if defined?(::Rails::Railtie)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require "rails/generators"
|
|
2
|
+
|
|
3
|
+
module Chronos
|
|
4
|
+
module Generators
|
|
5
|
+
# Generates the explicit Chronos initializer for legacy Rails applications.
|
|
6
|
+
#
|
|
7
|
+
# @responsibility Copy one documented initializer into config/initializers.
|
|
8
|
+
# @motivation Keep credentials explicit and avoid automatic environment scanning.
|
|
9
|
+
# @limits It does not modify routes, application classes, or Gemfiles.
|
|
10
|
+
# @collaborators Rails::Generators::Base file-copy API.
|
|
11
|
+
# @thread_safety Generator instances are used serially by the Rails command.
|
|
12
|
+
# @compatibility Rails generator APIs available in Rails 4.2 through Rails 5.2.
|
|
13
|
+
# @example
|
|
14
|
+
# rails generate chronos:install
|
|
15
|
+
# @errors Existing-file conflict handling is delegated to Rails generators.
|
|
16
|
+
# @performance Copies one small text file.
|
|
17
|
+
class InstallGenerator < ::Rails::Generators::Base
|
|
18
|
+
source_root File.expand_path("templates", __dir__)
|
|
19
|
+
|
|
20
|
+
def create_initializer
|
|
21
|
+
copy_file "chronos.rb", "config/initializers/chronos.rb"
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require "chronos/rails"
|
|
2
|
+
|
|
3
|
+
Chronos.configure do |config|
|
|
4
|
+
# Chronos reads only the environment variables explicitly selected here.
|
|
5
|
+
config.project_id = ENV["CHRONOS_PROJECT_ID"]
|
|
6
|
+
config.project_key = ENV["CHRONOS_PROJECT_KEY"]
|
|
7
|
+
config.host = ENV["CHRONOS_HOST"]
|
|
8
|
+
config.environment = Rails.env.to_s
|
|
9
|
+
config.service_name = ENV["CHRONOS_SERVICE_NAME"]
|
|
10
|
+
config.app_version = ENV["CHRONOS_APP_VERSION"]
|
|
11
|
+
config.logger = Rails.logger if Rails.respond_to?(:logger)
|
|
12
|
+
|
|
13
|
+
# Safe legacy defaults: test and console integrations remain disabled.
|
|
14
|
+
config.rails_capture_in_test = false
|
|
15
|
+
config.rails_capture_in_console = false
|
|
16
|
+
config.rails_capture_user_agent = false
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Safe when the Railtie already ran or will run later; installation is idempotent.
|
|
20
|
+
Chronos::Rails::Installer.new.install(Rails.application)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: chronos-ruby
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0.pre.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Antonio Jefferson
|
|
@@ -87,6 +87,7 @@ files:
|
|
|
87
87
|
- README.md
|
|
88
88
|
- SECURITY.md
|
|
89
89
|
- contracts/event-v1.schema.json
|
|
90
|
+
- contracts/rack-context-v1.schema.json
|
|
90
91
|
- docs/adr/ADR-001-core-and-integrations.md
|
|
91
92
|
- docs/adr/ADR-002-version-lines.md
|
|
92
93
|
- docs/adr/ADR-003-net-http-legacy-transport.md
|
|
@@ -94,6 +95,8 @@ files:
|
|
|
94
95
|
- docs/adr/ADR-005-sanitize-before-backlog.md
|
|
95
96
|
- docs/adr/ADR-006-versioned-event-contract.md
|
|
96
97
|
- docs/adr/ADR-011-bounded-resilience-and-remote-control.md
|
|
98
|
+
- docs/adr/ADR-012-rack-context-isolation.md
|
|
99
|
+
- docs/adr/ADR-013-legacy-rails-notifications.md
|
|
97
100
|
- docs/architecture.md
|
|
98
101
|
- docs/compatibility.md
|
|
99
102
|
- docs/configuration.md
|
|
@@ -102,10 +105,13 @@ files:
|
|
|
102
105
|
- docs/modules/async-queue.md
|
|
103
106
|
- docs/modules/configuration.md
|
|
104
107
|
- docs/modules/notice-pipeline.md
|
|
108
|
+
- docs/modules/rack-context.md
|
|
109
|
+
- docs/modules/rails-legacy.md
|
|
105
110
|
- docs/modules/remote-configuration.md
|
|
106
111
|
- docs/modules/retry-backlog.md
|
|
107
112
|
- docs/modules/sanitization.md
|
|
108
113
|
- docs/modules/serialization.md
|
|
114
|
+
- docs/modules/telemetry-events.md
|
|
109
115
|
- docs/modules/transport.md
|
|
110
116
|
- docs/performance.md
|
|
111
117
|
- docs/privacy-lgpd.md
|
|
@@ -113,16 +119,21 @@ files:
|
|
|
113
119
|
- lib/chronos.rb
|
|
114
120
|
- lib/chronos/adapters.rb
|
|
115
121
|
- lib/chronos/adapters/net_http_transport.rb
|
|
122
|
+
- lib/chronos/adapters/thread_local_context_store.rb
|
|
116
123
|
- lib/chronos/agent.rb
|
|
117
124
|
- lib/chronos/application.rb
|
|
118
125
|
- lib/chronos/application/capture_exception.rb
|
|
126
|
+
- lib/chronos/application/capture_telemetry.rb
|
|
119
127
|
- lib/chronos/application/circuit_breaker.rb
|
|
120
128
|
- lib/chronos/application/delivery_pipeline.rb
|
|
121
129
|
- lib/chronos/application/remote_configuration.rb
|
|
122
130
|
- lib/chronos/application/retry_policy.rb
|
|
123
131
|
- lib/chronos/configuration.rb
|
|
132
|
+
- lib/chronos/configuration/snapshot.rb
|
|
133
|
+
- lib/chronos/configuration/validation.rb
|
|
124
134
|
- lib/chronos/core.rb
|
|
125
135
|
- lib/chronos/core/backtrace_parser.rb
|
|
136
|
+
- lib/chronos/core/breadcrumb.rb
|
|
126
137
|
- lib/chronos/core/exception_cause_collector.rb
|
|
127
138
|
- lib/chronos/core/notice.rb
|
|
128
139
|
- lib/chronos/core/notice_builder.rb
|
|
@@ -131,17 +142,28 @@ files:
|
|
|
131
142
|
- lib/chronos/core/safe_serializer.rb
|
|
132
143
|
- lib/chronos/core/sanitizer.rb
|
|
133
144
|
- lib/chronos/core/sensitive_value_filter.rb
|
|
145
|
+
- lib/chronos/core/telemetry_event.rb
|
|
134
146
|
- lib/chronos/errors.rb
|
|
147
|
+
- lib/chronos/integrations.rb
|
|
148
|
+
- lib/chronos/integrations/rack.rb
|
|
149
|
+
- lib/chronos/integrations/rack/middleware.rb
|
|
135
150
|
- lib/chronos/internal.rb
|
|
136
151
|
- lib/chronos/internal/bounded_queue.rb
|
|
137
152
|
- lib/chronos/internal/memory_backlog.rb
|
|
138
153
|
- lib/chronos/internal/safe_logger.rb
|
|
139
154
|
- lib/chronos/internal/worker_pool.rb
|
|
140
155
|
- lib/chronos/ports.rb
|
|
156
|
+
- lib/chronos/ports/context_store.rb
|
|
141
157
|
- lib/chronos/ports/transport.rb
|
|
158
|
+
- lib/chronos/rails.rb
|
|
159
|
+
- lib/chronos/rails/installer.rb
|
|
160
|
+
- lib/chronos/rails/notifications_subscriber.rb
|
|
161
|
+
- lib/chronos/rails/railtie.rb
|
|
142
162
|
- lib/chronos/ruby.rb
|
|
143
163
|
- lib/chronos/ruby/version.rb
|
|
144
164
|
- lib/chronos/version.rb
|
|
165
|
+
- lib/generators/chronos/install/install_generator.rb
|
|
166
|
+
- lib/generators/chronos/install/templates/chronos.rb
|
|
145
167
|
homepage: https://github.com/antoniojefferson/chronos-ruby
|
|
146
168
|
licenses:
|
|
147
169
|
- MIT
|