Class: Salopulse::Client
- Inherits:
-
Object
- Object
- Salopulse::Client
- Includes:
- Singleton
- Defined in:
- lib/salopulse/client.rb
Instance Attribute Summary collapse
-
#buffer ⇒ Object
readonly
Returns the value of attribute buffer.
-
#configuration ⇒ Object
readonly
Returns the value of attribute configuration.
-
#dsn ⇒ Object
readonly
Returns the value of attribute dsn.
-
#flusher ⇒ Object
readonly
Returns the value of attribute flusher.
-
#transport ⇒ Object
readonly
Returns the value of attribute transport.
Instance Method Summary collapse
- #capture_exception(error, user_context: nil, environment_data: nil) ⇒ Object
- #capture_message(message, level: :info) ⇒ Object
- #capture_performance(endpoint:, http_method:, duration_ms:, status_code:, cpu_usage: nil, memory_usage: nil) ⇒ Object
-
#capture_sql(query:, duration_ms:, rows_returned: nil) ⇒ Object
— Capture API ———————————————————.
- #close ⇒ Object
- #disabled? ⇒ Boolean
-
#flush(timeout: 5) ⇒ Object
— Lifecycle ———————————————————–.
-
#flush_request_scope_events ⇒ Object
— Request scope ——————————————————-.
- #init(options = {}) ⇒ Object
-
#initialize ⇒ Client
constructor
A new instance of Client.
- #initialized? ⇒ Boolean
-
#reset! ⇒ Object
Used by tests to wipe singleton state.
- #set_tag(key, value) ⇒ Object
-
#set_user(attrs) ⇒ Object
— Context helpers —————————————————–.
- #uninitialized? ⇒ Boolean
Constructor Details
#initialize ⇒ Client
Returns a new instance of Client.
21 22 23 24 25 |
# File 'lib/salopulse/client.rb', line 21 def initialize @initialized = false @mutex = Mutex.new @pid = nil end |
Instance Attribute Details
#buffer ⇒ Object (readonly)
Returns the value of attribute buffer.
19 20 21 |
# File 'lib/salopulse/client.rb', line 19 def buffer @buffer end |
#configuration ⇒ Object (readonly)
Returns the value of attribute configuration.
19 20 21 |
# File 'lib/salopulse/client.rb', line 19 def configuration @configuration end |
#dsn ⇒ Object (readonly)
Returns the value of attribute dsn.
19 20 21 |
# File 'lib/salopulse/client.rb', line 19 def dsn @dsn end |
#flusher ⇒ Object (readonly)
Returns the value of attribute flusher.
19 20 21 |
# File 'lib/salopulse/client.rb', line 19 def flusher @flusher end |
#transport ⇒ Object (readonly)
Returns the value of attribute transport.
19 20 21 |
# File 'lib/salopulse/client.rb', line 19 def transport @transport end |
Instance Method Details
#capture_exception(error, user_context: nil, environment_data: nil) ⇒ Object
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/salopulse/client.rb', line 93 def capture_exception(error, user_context: nil, environment_data: nil) return if disabled? return unless sample? ctx = RequestContext.current backtrace = Array(error.backtrace) data = { "error_class" => error.class.name, "message" => error..to_s, "stack_trace" => backtrace.join("\n"), "stack_frames" => StackFrameBuilder.call(backtrace, app_root: configuration&.app_root), "endpoint" => ctx&.dig(:endpoint), "http_method" => ctx&.dig(:http_method) } user = user_context || ctx&.dig(:user) data["user_context"] = Sanitizer.scrub_hash(user) if user data["environment_data"] = Sanitizer.scrub_hash(environment_data) if environment_data enqueue(build_event(type: "error", data: data.compact, ctx: ctx)) end |
#capture_message(message, level: :info) ⇒ Object
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/salopulse/client.rb', line 114 def (, level: :info) return if disabled? return unless sample? ctx = RequestContext.current data = { "error_class" => "Salopulse::Message", "message" => .to_s, "stack_trace" => "", "endpoint" => ctx&.dig(:endpoint), "http_method" => ctx&.dig(:http_method), "level" => level.to_s }.compact enqueue(build_event(type: "error", data: data, ctx: ctx)) end |
#capture_performance(endpoint:, http_method:, duration_ms:, status_code:, cpu_usage: nil, memory_usage: nil) ⇒ Object
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/salopulse/client.rb', line 130 def capture_performance(endpoint:, http_method:, duration_ms:, status_code:, cpu_usage: nil, memory_usage: nil) return if disabled? return unless sample? ctx = RequestContext.current data = { "endpoint" => endpoint, "http_method" => http_method, "duration_ms" => duration_ms.to_i, "status_code" => status_code.to_i } data["cpu_usage"] = cpu_usage if cpu_usage data["memory_usage"] = memory_usage if memory_usage enqueue(build_event(type: "performance", data: data, ctx: ctx)) end |
#capture_sql(query:, duration_ms:, rows_returned: nil) ⇒ Object
— Capture API ———————————————————
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/salopulse/client.rb', line 64 def capture_sql(query:, duration_ms:, rows_returned: nil) return if disabled? return if RequestContext.suppressed? return unless sample? ctx = RequestContext.current fingerprint = LocalFingerprint.for(query) event = build_event( type: "sql", data: { "query" => query, "duration_ms" => duration_ms.to_i, "endpoint" => ctx&.dig(:endpoint), "http_method" => ctx&.dig(:http_method), "rows_returned" => rows_returned, "n1_detected" => false }.compact, ctx: ctx, extra_envelope: { "database_dialect" => detect_dialect } ) if ctx RequestContext.record_sql_event(event, fingerprint) else enqueue(event) end end |
#close ⇒ Object
182 183 184 185 186 187 188 |
# File 'lib/salopulse/client.rb', line 182 def close return unless @initialized ensure_runtime_ready! @flusher&.stop(timeout: 5) @pid = nil @initialized = false end |
#disabled? ⇒ Boolean
58 59 60 |
# File 'lib/salopulse/client.rb', line 58 def disabled? !@initialized || !@configuration&.enabled end |
#flush(timeout: 5) ⇒ Object
— Lifecycle ———————————————————–
176 177 178 179 180 |
# File 'lib/salopulse/client.rb', line 176 def flush(timeout: 5) return 0 if disabled? ensure_runtime_ready! @flusher.flush_all(timeout: timeout) end |
#flush_request_scope_events ⇒ Object
— Request scope ——————————————————-
149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/salopulse/client.rb', line 149 def flush_request_scope_events ctx = RequestContext.current return unless ctx threshold = @configuration.n1_threshold counts = ctx[:sql_fingerprint_counts] ctx[:sql_events].each do |event, fingerprint| if counts[fingerprint] >= threshold event[:data]["n1_detected"] = true end enqueue(event) end end |
#init(options = {}) ⇒ Object
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/salopulse/client.rb', line 27 def init( = {}) @mutex.synchronize do if @initialized build_runtime!(reset_buffer: forked_process?) unless runtime_ready? return self end @configuration = Configuration.new .each { |k, v| @configuration.public_send("#{k}=", v) if @configuration.respond_to?("#{k}=") } return self unless @configuration.enabled @dsn = DSN.new(@configuration.dsn) build_runtime!(reset_buffer: true) install_at_exit_hook @initialized = true announce_deploy! self end end |
#initialized? ⇒ Boolean
50 51 52 |
# File 'lib/salopulse/client.rb', line 50 def initialized? @initialized end |
#reset! ⇒ Object
Used by tests to wipe singleton state.
191 192 193 194 195 196 197 198 199 200 201 |
# File 'lib/salopulse/client.rb', line 191 def reset! close if @initialized @configuration = nil @buffer = nil @transport = nil @flusher = nil @dsn = nil @pid = nil @initialized = false @deploy_announced = false end |
#set_tag(key, value) ⇒ Object
170 171 172 |
# File 'lib/salopulse/client.rb', line 170 def set_tag(key, value) RequestContext.set_tag(key, value) end |
#set_user(attrs) ⇒ Object
— Context helpers —————————————————–
166 167 168 |
# File 'lib/salopulse/client.rb', line 166 def set_user(attrs) RequestContext.set_user(attrs) end |
#uninitialized? ⇒ Boolean
54 55 56 |
# File 'lib/salopulse/client.rb', line 54 def uninitialized? !@initialized end |