Class: Ditliti::Client
- Inherits:
-
Object
- Object
- Ditliti::Client
- Defined in:
- lib/ditliti.rb
Instance Attribute Summary collapse
-
#session_id ⇒ Object
Returns the value of attribute session_id.
-
#trace ⇒ Object
readonly
Returns the value of attribute trace.
-
#user ⇒ Object
Returns the value of attribute user.
Instance Method Summary collapse
- #add_breadcrumb(message:, category: nil, level: "info", data: {}) ⇒ Object
- #capture_exception(error, context: {}, tags: {}, transaction: nil, user_agent: nil) ⇒ Object
- #capture_profile(duration_ms:, trace_id: nil, transaction: nil, platform: "ruby", samples: [], tags: {}, release: @release, environment: @environment) ⇒ Object
- #capture_rack_exception(error, env) ⇒ Object
- #capture_replay_segment(duration_ms:, session_id: @session_id, segment_index: 0, events: [], tags: {}, user: @user, release: @release, environment: @environment) ⇒ Object
- #get_traceparent ⇒ Object
-
#initialize(endpoint:, api_key:, project_id:, release: nil, environment: nil, timeout: 1.5) ⇒ Client
constructor
A new instance of Client.
- #record_span(trace_id:, span_id:, operation_name:, duration_ms:, parent_span_id: nil, started_at: nil, tags: {}) ⇒ Object
- #send_envelope(envelope) ⇒ Object
-
#start_span(operation_name, tags: {}) ⇒ Object
Start a child span under the active trace (starting one implicitly if none is active yet).
-
#start_trace(incoming_traceparent = nil) ⇒ Object
Start (or continue, if an inbound
traceparentheader is given) the active trace.
Constructor Details
#initialize(endpoint:, api_key:, project_id:, release: nil, environment: nil, timeout: 1.5) ⇒ Client
Returns a new instance of Client.
101 102 103 104 105 106 107 108 109 110 |
# File 'lib/ditliti.rb', line 101 def initialize(endpoint:, api_key:, project_id:, release: nil, environment: nil, timeout: 1.5) @endpoint = endpoint.sub(%r{/$}, "") @api_key = api_key @project_id = project_id @release = release @environment = environment @timeout = timeout @breadcrumbs = [] @trace = nil end |
Instance Attribute Details
#session_id ⇒ Object
Returns the value of attribute session_id.
98 99 100 |
# File 'lib/ditliti.rb', line 98 def session_id @session_id end |
#trace ⇒ Object (readonly)
Returns the value of attribute trace.
99 100 101 |
# File 'lib/ditliti.rb', line 99 def trace @trace end |
#user ⇒ Object
Returns the value of attribute user.
98 99 100 |
# File 'lib/ditliti.rb', line 98 def user @user end |
Instance Method Details
#add_breadcrumb(message:, category: nil, level: "info", data: {}) ⇒ Object
161 162 163 164 165 166 167 168 169 170 |
# File 'lib/ditliti.rb', line 161 def (message:, category: nil, level: "info", data: {}) @breadcrumbs << { timestamp: Time.now.utc.iso8601, category: category, message: .to_s, level: level, data: data || {} } @breadcrumbs.shift while @breadcrumbs.length > 100 end |
#capture_exception(error, context: {}, tags: {}, transaction: nil, user_agent: nil) ⇒ Object
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/ditliti.rb', line 172 def capture_exception(error, context: {}, tags: {}, transaction: nil, user_agent: nil) payload = { id: SecureRandom.uuid, project_id: @project_id, level: "error", message: error..to_s, exception_type: error.class.name, stack_trace: stack_frames(error), tags: { runtime: "ruby" }.merge().merge( || {}), context: context || {}, user_agent: user_agent, release: @release, environment: @environment, transaction: transaction, session_id: @session_id, breadcrumbs: @breadcrumbs, user: @user } post("/api/v1/ingest", payload, stable_id(payload)) end |
#capture_profile(duration_ms:, trace_id: nil, transaction: nil, platform: "ruby", samples: [], tags: {}, release: @release, environment: @environment) ⇒ Object
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 |
# File 'lib/ditliti.rb', line 240 def capture_profile(duration_ms:, trace_id: nil, transaction: nil, platform: "ruby", samples: [], tags: {}, release: @release, environment: @environment) send_envelope({ profiles: [{ project_id: @project_id, trace_id: trace_id || @trace&.trace_id, transaction: transaction, started_at: Time.now.utc.iso8601, duration_ms: duration_ms, platform: platform, samples: samples || [], tags: { runtime: "ruby" }.merge( || {}), release: release, environment: environment }] }) end |
#capture_rack_exception(error, env) ⇒ Object
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/ditliti.rb', line 193 def capture_rack_exception(error, env) request_method = env["REQUEST_METHOD"] path = env["PATH_INFO"] || env["REQUEST_URI"] capture_exception( error, context: { framework: "rack", method: request_method, path: path, query: env["QUERY_STRING"] }, tags: { framework: "rack" }, transaction: "#{request_method || "HTTP"} #{path || "/"}", user_agent: env["HTTP_USER_AGENT"] ) end |
#capture_replay_segment(duration_ms:, session_id: @session_id, segment_index: 0, events: [], tags: {}, user: @user, release: @release, environment: @environment) ⇒ Object
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 |
# File 'lib/ditliti.rb', line 221 def capture_replay_segment(duration_ms:, session_id: @session_id, segment_index: 0, events: [], tags: {}, user: @user, release: @release, environment: @environment) raise ArgumentError, "replay session_id is required" if session_id.nil? || session_id.to_s.empty? send_envelope({ replays: [{ project_id: @project_id, session_id: session_id, started_at: Time.now.utc.iso8601, duration_ms: duration_ms, segment_index: segment_index, events: events || [], tags: { runtime: "ruby" }.merge( || {}), user: user, release: release, environment: environment }] }) end |
#get_traceparent ⇒ Object
122 123 124 |
# File 'lib/ditliti.rb', line 122 def get_traceparent @trace&.to_traceparent end |
#record_span(trace_id:, span_id:, operation_name:, duration_ms:, parent_span_id: nil, started_at: nil, tags: {}) ⇒ Object
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/ditliti.rb', line 135 def record_span(trace_id:, span_id:, operation_name:, duration_ms:, parent_span_id: nil, started_at: nil, tags: {}) = { runtime: "ruby" } [:environment] = @environment if @environment [:release] = @release if @release send_envelope({ spans: [{ trace_id: trace_id, span_id: span_id, parent_span_id: parent_span_id, project_id: @project_id, operation_name: operation_name, start_time: (started_at || Time.now.utc).iso8601(3), duration_ms: duration_ms, tags: .merge() }] }) end |
#send_envelope(envelope) ⇒ Object
210 211 212 213 214 215 216 217 218 219 |
# File 'lib/ditliti.rb', line 210 def send_envelope(envelope) post("/api/v1/envelope", { project_id: @project_id, events: envelope.fetch(:events, []), spans: envelope.fetch(:spans, []), logs: envelope.fetch(:logs, []), replays: envelope.fetch(:replays, []), profiles: envelope.fetch(:profiles, []) }) end |
#start_span(operation_name, tags: {}) ⇒ Object
Start a child span under the active trace (starting one implicitly if none is active yet).
128 129 130 131 132 133 |
# File 'lib/ditliti.rb', line 128 def start_span(operation_name, tags: {}) start_trace if @trace.nil? parent_span_id = @trace.span_id ctx = @trace.child Span.new(self, operation_name, parent_span_id, ctx, { runtime: "ruby" }.merge()) end |
#start_trace(incoming_traceparent = nil) ⇒ Object
Start (or continue, if an inbound traceparent header is given) the
active trace. Downstream calls should read #get_traceparent and
forward it as the traceparent header of any outgoing HTTP request to
propagate the trace into the next service.
116 117 118 119 120 |
# File 'lib/ditliti.rb', line 116 def start_trace(incoming_traceparent = nil) parent = TraceContext.from_traceparent(incoming_traceparent) @trace = parent ? parent.child : TraceContext.start @trace end |