Class: Datadog::DI::ProbeNotificationBuilder Private
- Inherits:
-
Object
- Object
- Datadog::DI::ProbeNotificationBuilder
- Defined in:
- lib/datadog/di/probe_notification_builder.rb
Overview
This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.
Builds probe status notification and snapshot payloads.
Instance Attribute Summary collapse
- #serializer ⇒ Object readonly private
- #settings ⇒ Object readonly private
Instance Method Summary collapse
- #build_emitting(probe) ⇒ Object private
-
#build_executed(probe, trace_point: nil, rv: nil, duration: nil, caller_locations: nil, args: nil, kwargs: nil, serialized_entry_args: nil) ⇒ Object
private
Duration is in seconds.
- #build_installed(probe) ⇒ Object private
- #build_received(probe) ⇒ Object private
- #build_snapshot(probe, rv: nil, snapshot: nil, path: nil, duration: nil, caller_locations: nil, args: nil, kwargs: nil, serialized_entry_args: nil) ⇒ Object private
- #build_status(probe, message:, status:) ⇒ Object private
- #evaluate_template(template, **vars) ⇒ Object private
- #format_caller_locations(caller_locations) ⇒ Object private
- #get_local_variables(trace_point) ⇒ Object private
-
#initialize(settings, serializer) ⇒ ProbeNotificationBuilder
constructor
private
A new instance of ProbeNotificationBuilder.
- #timestamp_now ⇒ Object private
Constructor Details
#initialize(settings, serializer) ⇒ ProbeNotificationBuilder
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns a new instance of ProbeNotificationBuilder.
9 10 11 12 |
# File 'lib/datadog/di/probe_notification_builder.rb', line 9 def initialize(settings, serializer) @settings = settings @serializer = serializer end |
Instance Attribute Details
#serializer ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
15 16 17 |
# File 'lib/datadog/di/probe_notification_builder.rb', line 15 def serializer @serializer end |
#settings ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
14 15 16 |
# File 'lib/datadog/di/probe_notification_builder.rb', line 14 def settings @settings end |
Instance Method Details
#build_emitting(probe) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
29 30 31 32 33 |
# File 'lib/datadog/di/probe_notification_builder.rb', line 29 def build_emitting(probe) build_status(probe, message: "Probe #{probe.id} is emitting", status: 'EMITTING',) end |
#build_executed(probe, trace_point: nil, rv: nil, duration: nil, caller_locations: nil, args: nil, kwargs: nil, serialized_entry_args: nil) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Duration is in seconds.
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/datadog/di/probe_notification_builder.rb', line 36 def build_executed(probe, trace_point: nil, rv: nil, duration: nil, caller_locations: nil, args: nil, kwargs: nil, serialized_entry_args: nil) snapshot = if probe.line? && probe.capture_snapshot? if trace_point.nil? raise "Cannot create snapshot because there is no trace point" end get_local_variables(trace_point) end # TODO check how many stack frames we should be keeping/sending, # this should be all frames for enriched probes and no frames for # non-enriched probes? build_snapshot(probe, rv: rv, snapshot: snapshot, # Actual path of the instrumented file. path: trace_point&.path, duration: duration, caller_locations: caller_locations, args: args, kwargs: kwargs, serialized_entry_args: serialized_entry_args) end |
#build_installed(probe) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
23 24 25 26 27 |
# File 'lib/datadog/di/probe_notification_builder.rb', line 23 def build_installed(probe) build_status(probe, message: "Probe #{probe.id} has been instrumented correctly", status: 'INSTALLED',) end |
#build_received(probe) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
17 18 19 20 21 |
# File 'lib/datadog/di/probe_notification_builder.rb', line 17 def build_received(probe) build_status(probe, message: "Probe #{probe.id} has been received correctly", status: 'RECEIVED',) end |
#build_snapshot(probe, rv: nil, snapshot: nil, path: nil, duration: nil, caller_locations: nil, args: nil, kwargs: nil, serialized_entry_args: nil) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
55 56 57 58 59 60 61 62 63 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 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/datadog/di/probe_notification_builder.rb', line 55 def build_snapshot(probe, rv: nil, snapshot: nil, path: nil, duration: nil, caller_locations: nil, args: nil, kwargs: nil, serialized_entry_args: nil) # TODO also verify that non-capturing probe does not pass # snapshot or vars/args into this method captures = if probe.capture_snapshot? if probe.method? { entry: { # standard:disable all arguments: if serialized_entry_args serialized_entry_args else (args || kwargs) && serializer.serialize_args(args, kwargs, depth: probe.max_capture_depth || settings.dynamic_instrumentation.max_capture_depth, attribute_count: probe.max_capture_attribute_count || settings.dynamic_instrumentation.max_capture_attribute_count) end, throwable: nil, # standard:enable all }, return: { arguments: { "@return": serializer.serialize_value(rv, depth: probe.max_capture_depth || settings.dynamic_instrumentation.max_capture_depth, attribute_count: probe.max_capture_attribute_count || settings.dynamic_instrumentation.max_capture_attribute_count), }, throwable: nil, }, } elsif probe.line? { lines: snapshot && { probe.line_no => {locals: serializer.serialize_vars(snapshot, depth: probe.max_capture_depth || settings.dynamic_instrumentation.max_capture_depth, attribute_count: probe.max_capture_attribute_count || settings.dynamic_instrumentation.max_capture_attribute_count,)}, }, } end end location = if probe.line? { file: path, lines: [probe.line_no], } elsif probe.method? { method: probe.method_name, type: probe.type_name, } end stack = if caller_locations format_caller_locations(caller_locations) end = { service: settings.service, "debugger.snapshot": { id: SecureRandom.uuid, timestamp: , evaluationErrors: [], probe: { id: probe.id, version: 0, location: location, }, language: 'ruby', # TODO add test coverage for callers being nil stack: stack, captures: captures, }, # In python tracer duration is under debugger.snapshot, # but UI appears to expect it here at top level. duration: duration ? (duration * 10**9).to_i : 0, host: nil, logger: { name: probe.file, method: probe.method_name || 'no_method', thread_name: Thread.current.name, # Dynamic instrumentation currently does not need thread_id for # anything. It can be sent if a customer requests it at which point # we can also determine which thread identifier to send # (Thread#native_thread_id or something else). thread_id: nil, version: 2, }, # TODO add tests that the trace/span id is correctly propagated "dd.trace_id": Datadog::Tracing.active_trace&.id&.to_s, "dd.span_id": Datadog::Tracing.active_span&.id&.to_s, ddsource: 'dd_debugger', message: probe.template && evaluate_template(probe.template, duration: duration ? duration * 1000 : 0), timestamp: , } end |
#build_status(probe, message:, status:) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/datadog/di/probe_notification_builder.rb', line 153 def build_status(probe, message:, status:) { service: settings.service, timestamp: , message: , ddsource: 'dd_debugger', debugger: { diagnostics: { probeId: probe.id, probeVersion: 0, runtimeId: Core::Environment::Identity.id, parentId: nil, status: status, }, }, } end |
#evaluate_template(template, **vars) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
177 178 179 180 181 182 183 |
# File 'lib/datadog/di/probe_notification_builder.rb', line 177 def evaluate_template(template, **vars) = template.dup vars.each do |key, value| .gsub!("{@#{key}}", value.to_s) end end |
#format_caller_locations(caller_locations) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
171 172 173 174 175 |
# File 'lib/datadog/di/probe_notification_builder.rb', line 171 def format_caller_locations(caller_locations) caller_locations.map do |loc| {fileName: loc.path, function: loc.label, lineNumber: loc.lineno} end end |
#get_local_variables(trace_point) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
189 190 191 192 193 194 195 196 197 198 199 200 201 202 |
# File 'lib/datadog/di/probe_notification_builder.rb', line 189 def get_local_variables(trace_point) # binding appears to be constructed on access, therefore # 1) we should attempt to cache it and # 2) we should not call +binding+ until we actually need variable values. binding = trace_point.binding # steep hack - should never happen return {} unless binding binding.local_variables.each_with_object({}) do |name, map| value = binding.local_variable_get(name) map[name] = value end end |
#timestamp_now ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
185 186 187 |
# File 'lib/datadog/di/probe_notification_builder.rb', line 185 def (Time.now.to_f * 1000).to_i end |