Module: Datadog::DI::ProbeBuilder Private

Defined in:
lib/datadog/di/probe_builder.rb

Overview

This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.

Creates Probe instances from remote configuration payloads.

Due to the dynamic instrumentation product evolving over time, it is possible that the payload corresponds to a type of probe that the current version of the library does not handle. For now ArgumentError is raised in such cases (by ProbeBuilder or Probe constructor), since generally DI is meant to rescue all exceptions internally and not propagate any exceptions to applications. A dedicated exception could be added in the future if there is a use case for it.

API:

  • private

Constant Summary collapse

PROBE_TYPES =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

API:

  • private

{
  'LOG_PROBE' => :log,
}.freeze

Class Method Summary collapse

Class Method Details

.build_from_remote_config(config) ⇒ 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.

API:

  • private



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/datadog/di/probe_builder.rb', line 29

def build_from_remote_config(config)
  # The validations here are not yet comprehensive.
  type = config.fetch('type')
  type_symbol = PROBE_TYPES[type] or raise ArgumentError, "Unrecognized probe type: #{type}"
  cond = if cond_spec = config['when']
    unless cond_spec['dsl'] && cond_spec['json']
      raise ArgumentError, "Malformed condition specification for probe: #{config}"
    end
    compiled = EL::Compiler.new.compile(cond_spec['json'])
    EL::Expression.new(cond_spec['dsl'], compiled)
  end
  Probe.new(
    id: config.fetch("id"),
    type: type_symbol,
    file: config["where"]&.[]("sourceFile"),
    # Sometimes lines are sometimes received as an array of nil
    # for some reason.
    line_no: config["where"]&.[]("lines")&.compact&.map(&:to_i)&.first,
    type_name: config["where"]&.[]("typeName"),
    method_name: config["where"]&.[]("methodName"),
    # We should not be using the template for anything - we instead
    # use +segments+ - but keep the template for debugging.
    template: config["template"],
    template_segments: build_template_segments(config['segments']),
    capture_snapshot: !!config["captureSnapshot"],
    max_capture_depth: config["capture"]&.[]("maxReferenceDepth"),
    max_capture_attribute_count: config["capture"]&.[]("maxFieldCount"),
    rate_limit: config["sampling"]&.[]("snapshotsPerSecond"),
    condition: cond,
  )
rescue KeyError => exc
  raise ArgumentError, "Malformed remote configuration entry for probe: #{exc.class}: #{exc}: #{config}"
end

.build_template_segments(segments) ⇒ 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.

API:

  • private



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/datadog/di/probe_builder.rb', line 63

def build_template_segments(segments)
  segments&.map do |segment|
    if Hash === segment
      if str = segment['str']
        str
      elsif ast = segment['json']
        unless dsl = segment['dsl']
          raise ArgumentError, "Missing dsl for json in segment: #{segment}"
        end
        compiled = EL::Compiler.new.compile(ast)
        EL::Expression.new(dsl, compiled)
      else
        # TODO report to telemetry?
      end
    else
      # TODO report to telemetry?
    end
  end&.compact
end