Skip to content

Commit

Permalink
Add stack_trace fields
Browse files Browse the repository at this point in the history
  • Loading branch information
TonyCTHsu committed Aug 29, 2024
1 parent 451d390 commit 4aae539
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 12 deletions.
16 changes: 10 additions & 6 deletions lib/datadog/core/telemetry/event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -346,19 +346,23 @@ def type
'logs'
end

def initialize(message:, level:)
def initialize(message:, level:, stack_trace: nil)
super()
@message = message
@stack_trace = stack_trace
@level = LEVELS.fetch(level) { |k| raise ArgumentError, "Invalid log level :#{k}" }
end

def payload
{
logs: [{
message: @message,
level: @level,
# More optional fields to be added here...
}]
logs: [
{
message: @message,
level: @level,
# More optional fields to be added here...
stack_trace: @stack_trace,
}.compact
]
}
end
end
Expand Down
23 changes: 22 additions & 1 deletion lib/datadog/core/telemetry/logging.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,26 @@ module Telemetry
module Logging
extend self

# Extract datadog stack trace from the exception
module DatadogStackTrace
REGEX = %r{datadog-.*?/lib/datadog/}.freeze

def self.from(exception)
return unless exception.backtrace

stack_trace = +''
(exception.backtrace || []).each do |line|
stack_trace << if line.match?(REGEX)
line.sub(/^.*?(#{REGEX})/o, '\1') << ','
else
'REDACTED,'
end
end

stack_trace.chomp(',')
end
end

def report(exception, level:, description: nil)
# Annoymous exceptions to be logged as <Class:0x00007f8b1c0b3b40>
message = +''
Expand All @@ -20,7 +40,8 @@ def report(exception, level:, description: nil)

event = Event::Log.new(
message: message,
level: level
level: level,
stack_trace: DatadogStackTrace.from(exception)
)

dispatch(event)
Expand Down
5 changes: 3 additions & 2 deletions sig/datadog/core/telemetry/event.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,11 @@ module Datadog

@message: String
@level: "ERROR" | "DEBUG" | "WARN"
@stack_trace: String?

def initialize: (message: String, level: Symbol) -> void
def initialize: (message: String, level: Symbol, ?stack_trace: String?) -> void

def payload: () -> { logs: [{ message: String, level: String }] }
def payload: () -> { logs: [Hash[Symbol, String]] }
end

class Distributions < GenerateMetrics
Expand Down
5 changes: 5 additions & 0 deletions sig/datadog/core/telemetry/logging.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ module Datadog
module Core
module Telemetry
module Logging
module DatadogStackTrace
REGEX: Regexp
def self.from: (Exception exception) -> String?
end

extend Datadog::Core::Telemetry::Logging

def report: (Exception exception, level: Symbol, ?description: String?) -> void
Expand Down
59 changes: 56 additions & 3 deletions spec/datadog/core/telemetry/logging_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@
telemetry = instance_double(Datadog::Core::Telemetry::Component)
allow(Datadog.send(:components)).to receive(:telemetry).and_return(telemetry)
expect(telemetry).to receive(:log!).with(instance_of(Datadog::Core::Telemetry::Event::Log)) do |event|
expect(event.payload).to include(logs: [{ message: 'RuntimeError', level: 'ERROR' }])
expect(event.payload).to include(
logs: [{ message: 'RuntimeError', level: 'ERROR',
stack_trace: a_string_including('REDACTED') }]
)
end

begin
Expand All @@ -25,7 +28,10 @@
telemetry = instance_double(Datadog::Core::Telemetry::Component)
allow(Datadog.send(:components)).to receive(:telemetry).and_return(telemetry)
expect(telemetry).to receive(:log!).with(instance_of(Datadog::Core::Telemetry::Event::Log)) do |event|
expect(event.payload).to include(logs: [{ message: 'RuntimeError:Must not contain PII', level: 'ERROR' }])
expect(event.payload).to include(
logs: [{ message: 'RuntimeError:Must not contain PII', level: 'ERROR',
stack_trace: a_string_including('REDACTED') }]
)
end

begin
Expand All @@ -42,7 +48,10 @@
telemetry = instance_double(Datadog::Core::Telemetry::Component)
allow(Datadog.send(:components)).to receive(:telemetry).and_return(telemetry)
expect(telemetry).to receive(:log!).with(instance_of(Datadog::Core::Telemetry::Event::Log)) do |event|
expect(event.payload).to include(logs: [{ message: /#<Class:/, level: 'ERROR' }])
expect(event.payload).to include(
logs: [{ message: /#<Class:/, level: 'ERROR',
stack_trace: a_string_including('REDACTED') }]
)
end

customer_exception = Class.new(StandardError)
Expand Down Expand Up @@ -100,3 +109,47 @@
end
end
end

RSpec.describe Datadog::Core::Telemetry::Logging::DatadogStackTrace do
describe '.from' do
it do
exception = StandardError.new('Yo!')

result = described_class.from(exception)

expect(result).to be_nil
end

it do
exception = StandardError.new('Yo!')
exception.set_backtrace([])

result = described_class.from(exception)

expect(result).to be_nil
end

it 'returns redacted stack trace' do
exception = StandardError.new('Yo!')
exception.set_backtrace(
[
'/usr/local/bundle/gems/datadog-2.3.0.beta1/lib/datadog/core/telemetry/logging.rb:1 in `report`',
'/foo/bar/baz.rb:1 in `baz`',
'/foo/bar.rb:1 in `bar`',
'/foo.rb:1 in `foo`',
]
)

result = described_class.from(exception)

expect(result).to eq(
[
'datadog-2.3.0.beta1/lib/datadog/core/telemetry/logging.rb:1 in `report`',
'REDACTED',
'REDACTED',
'REDACTED'
].join(',')
)
end
end
end

0 comments on commit 4aae539

Please sign in to comment.