Module: MetrixWire
- Defined in:
- lib/metrixwire.rb,
lib/metrixwire/rack.rb,
lib/metrixwire/span.rb,
lib/metrixwire/trace.rb,
lib/metrixwire/config.rb,
lib/metrixwire/context.rb,
lib/metrixwire/railtie.rb,
lib/metrixwire/version.rb,
lib/metrixwire/transport.rb,
lib/metrixwire/instrument/pg.rb,
lib/metrixwire/instrument/redis.rb,
lib/metrixwire/instrument/mysql2.rb,
lib/metrixwire/instrument/helpers.rb,
lib/metrixwire/instrument/sqlite3.rb,
lib/metrixwire/instrument/net_http.rb,
lib/metrixwire/instrument/rack_builder.rb,
lib/metrixwire/instrument/active_support.rb,
lib/metrixwire/instrument/source_location.rb
Overview
Zero-config APM SDK for Ruby. Call MetrixWire.init once (or, in Rails, just add the gem + set METRIXWIRE_KEY and it's fully automatic). Every HTTP request becomes a trace and every DB query / outbound HTTP call / cache op within it becomes a span. There is no manual span API and no middleware to wire up.
Non-blocking: traces are batched on a background thread with a short send timeout, and ALL transport errors are swallowed — instrumentation must never throw into or block the host application.
Defined Under Namespace
Modules: Context, Instrument Classes: Config, Rack, Railtie, Span, Trace, Transport
Constant Summary collapse
- VERSION =
"0.2.4"
Class Method Summary collapse
-
.capture_exception(err) ⇒ Object
Escape hatch mirroring Node/PHP: attach an exception to the active trace for frameworks the SDK can't hook automatically.
- .capture_source? ⇒ Boolean
- .enabled? ⇒ Boolean
- .endpoint ⇒ Object
-
.enqueue(trace) ⇒ Object
Enqueue a finished trace for delivery.
-
.exception_meta(err) ⇒ Object
Build the ExceptionMeta hash from an arbitrary error.
-
.flush ⇒ Object
Manually flush the queue (e.g. before a short-lived process exits).
-
.init(opts = {}) ⇒ Object
Initialize the SDK.
- .initialized? ⇒ Boolean
-
.iso8601(time) ⇒ Object
ISO8601 UTC with millisecond precision, e.g.
-
.memory_delta_mb(start_kb) ⇒ Object
Memory delta in MB since
start_kb. -
.monotonic_ms ⇒ Object
Monotonic milliseconds — safe for measuring durations (never goes back).
-
.rss_kb ⇒ Object
Current process RSS in KB (best-effort, portable-ish).
Class Method Details
.capture_exception(err) ⇒ Object
Escape hatch mirroring Node/PHP: attach an exception to the active trace for frameworks the SDK can't hook automatically. NOT a manual span API.
87 88 89 90 91 92 93 |
# File 'lib/metrixwire.rb', line 87 def capture_exception(err) trace = Context.current trace&.capture_exception(err) nil rescue StandardError nil end |
.capture_source? ⇒ Boolean
67 68 69 |
# File 'lib/metrixwire.rb', line 67 def capture_source? @config ? @config.capture_source : true end |
.enabled? ⇒ Boolean
63 64 65 |
# File 'lib/metrixwire.rb', line 63 def enabled? @config ? @config.enabled : false end |
.endpoint ⇒ Object
71 72 73 |
# File 'lib/metrixwire.rb', line 71 def endpoint @config ? @config.endpoint : nil end |
.enqueue(trace) ⇒ Object
Enqueue a finished trace for delivery. Internal — used by instrumentation.
76 77 78 |
# File 'lib/metrixwire.rb', line 76 def enqueue(trace) @transport&.enqueue(trace) end |
.exception_meta(err) ⇒ Object
Build the ExceptionMeta hash from an arbitrary error. Keeps the top ~8 backtrace frames — enough to fingerprint and guide a fix.
111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/metrixwire.rb', line 111 def (err) return nil if err.nil? { type: err.class.name.to_s, message: err.respond_to?(:message) ? err..to_s : err.to_s, stack: (err.respond_to?(:backtrace) && err.backtrace ? err.backtrace.first(8).join("\n") : nil) }.compact rescue StandardError nil end |
.flush ⇒ Object
Manually flush the queue (e.g. before a short-lived process exits).
81 82 83 |
# File 'lib/metrixwire.rb', line 81 def flush @transport&.flush_sync end |
.init(opts = {}) ⇒ Object
Initialize the SDK. Args fall back to ENV: METRIXWIRE_KEY, METRIXWIRE_ENDPOINT, METRIXWIRE_ENABLED. Idempotent — a second call is a no-op. Auto-installs every instrumentation whose library is present.
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/metrixwire.rb', line 36 def init(opts = {}) return if @config # already initialised @config = Config.new(opts || {}) @transport = Transport.new(@config) warn("[metrixwire] no apiKey provided — SDK disabled.") if @config.api_key.empty? && !opts_disabled?(opts) if @config.enabled @transport.start install_all end nil rescue StandardError => e # init itself must never break the host app. begin warn("[metrixwire] init failed: #{e.}") rescue StandardError nil end nil end |
.initialized? ⇒ Boolean
59 60 61 |
# File 'lib/metrixwire.rb', line 59 def initialized? !@config.nil? end |
.iso8601(time) ⇒ Object
ISO8601 UTC with millisecond precision, e.g. "2026-07-14T10:00:00.000Z".
103 104 105 106 107 |
# File 'lib/metrixwire.rb', line 103 def iso8601(time) time.utc.strftime("%Y-%m-%dT%H:%M:%S.%LZ") rescue StandardError Time.now.utc.strftime("%Y-%m-%dT%H:%M:%S.%LZ") end |
.memory_delta_mb(start_kb) ⇒ Object
Memory delta in MB since start_kb. Returns 0 when unavailable.
140 141 142 143 144 145 146 147 148 149 |
# File 'lib/metrixwire.rb', line 140 def memory_delta_mb(start_kb) return 0 if start_kb.nil? now = rss_kb return 0 if now.nil? ((now - start_kb) / 1024.0).round rescue StandardError 0 end |
.monotonic_ms ⇒ Object
Monotonic milliseconds — safe for measuring durations (never goes back).
98 99 100 |
# File 'lib/metrixwire.rb', line 98 def monotonic_ms Process.clock_gettime(Process::CLOCK_MONOTONIC) * 1000.0 end |
.rss_kb ⇒ Object
Current process RSS in KB (best-effort, portable-ish). Used to compute a per-request memory delta for the memory_spike detector.
125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/metrixwire.rb', line 125 def rss_kb # Linux: read RSS pages straight from /proc (no fork, fast). if File.readable?("/proc/self/statm") status = File.read("/proc/self/statm") pages = status.split[1].to_i return pages * (page_size / 1024) end # macOS / BSD: shell out to ps (cheap, once per request boundary). out = `ps -o rss= -p #{Process.pid} 2>/dev/null`.to_s.strip out.empty? ? nil : out.to_i rescue StandardError nil end |