Class: Datadog::AppSec::ActionsHandler::SerializableBacktrace

Inherits:
Object
  • Object
show all
Defined in:
lib/datadog/appsec/actions_handler/serializable_backtrace.rb

Overview

This module serves encapsulates MessagePack serialization for caller locations.

It serializes part of the stack: up to 32 frames (configurable) keeping frames from top and bottom of the stack (75% to 25%, configurable).

It represents the stack trace that is added to span metastruct field.

Constant Summary collapse

CLASS_AND_FUNCTION_NAME_REGEX =
/\b((?:\w+::)*\w+)?[#.]?\b(\w+)\z/.freeze

Instance Method Summary collapse

Constructor Details

#initialize(locations:, stack_id:) ⇒ SerializableBacktrace

Returns a new instance of SerializableBacktrace.



16
17
18
19
# File 'lib/datadog/appsec/actions_handler/serializable_backtrace.rb', line 16

def initialize(locations:, stack_id:)
  @stack_id = stack_id
  @locations = locations
end

Instance Method Details

#to_msgpack(packer = nil) ⇒ Object



21
22
23
24
25
26
27
28
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
62
63
# File 'lib/datadog/appsec/actions_handler/serializable_backtrace.rb', line 21

def to_msgpack(packer = nil)
  # JRuby doesn't pass the packer
  packer ||= MessagePack::Packer.new

  packer.write_map_header(3)

  packer.write('id')
  packer.write(@stack_id.encode('UTF-8'))

  packer.write('language')
  packer.write('ruby'.encode('UTF-8'))

  serializable_locations_map = build_serializable_locations_map

  packer.write('frames')
  packer.write_array_header(serializable_locations_map.size)

  serializable_locations_map.each do |frame_id, location|
    packer.write_map_header(6)

    packer.write('id')
    packer.write(frame_id)

    packer.write('text')
    packer.write(location.to_s.encode('UTF-8'))

    packer.write('file')
    packer.write(location.path&.encode('UTF-8'))

    packer.write('line')
    packer.write(location.lineno)

    class_name, function_name = location.label&.match(CLASS_AND_FUNCTION_NAME_REGEX)&.captures

    packer.write('class_name')
    packer.write(class_name&.encode('UTF-8'))

    packer.write('function')
    packer.write(function_name&.encode('UTF-8'))
  end

  packer
end