This repository has been archived by the owner on Feb 18, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
rspec_honeycomb_formatter.rb
126 lines (108 loc) · 5.17 KB
/
rspec_honeycomb_formatter.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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
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
# frozen_string_literal: true
require 'rspec_honeycomb_formatter/version'
require 'rspec/core/formatters'
require 'honeycomb-beeline'
Honeycomb.configure do |config|
# override client if no configuration is provided, so that the pesky libhoney warning about lack of configuration is not shown
# except when we set HONEYCOMB_DEBUG to true - in which case we want to see the output locally
unless (ENV['HONEYCOMB_WRITEKEY'] && ENV['HONEYCOMB_DATASET']) || ENV['HONEYCOMB_DEBUG'] == 'true'
config.client = Libhoney::NullClient.new
end
end
unless Honeycomb.current_span
process_span = Honeycomb.start_span(name: File.basename($PROGRAM_NAME), serialized_trace: ENV['HTTP_X_HONEYCOMB_TRACE'])
ENV['HTTP_X_HONEYCOMB_TRACE'] = process_span.to_trace_header unless ENV['HTTP_X_HONEYCOMB_TRACE']
Honeycomb.add_field_to_trace('process.full_name', $PROGRAM_NAME)
Honeycomb.add_field_to_trace('process.args', ARGV)
at_exit do
if $ERROR_INFO&.is_a?(SystemExit)
process_span.add_field('process.exit_code', $ERROR_INFO.status)
elsif $ERROR_INFO
process_span.add_field('process.exit_code', $ERROR_INFO.class.name)
else
process_span.add_field('process.exit_code', 'unknown')
end
process_span.send
end
end
# A custom formatter for RSpec that posts messages to https://honeycomb.io for analysis
class RSpecHoneycombFormatter
::RSpec::Core::Formatters.register self, :start,
:example_group_started, :example_group_finished,
:example_started, :example_passed, :example_failed, :example_pending, :message,
:stop, :start_dump, :seed
def initialize(_output)
@group_stack = []
end
def start(notification)
@start_span = Honeycomb.start_span(name: 'rspec', serialized_trace: ENV['HTTP_X_HONEYCOMB_TRACE'])
ENV['HTTP_X_HONEYCOMB_TRACE'] = @start_span.to_trace_header unless ENV['HTTP_X_HONEYCOMB_TRACE']
@start_span.add_field('rspec.example_count', notification.count)
@start_span.add_field('rspec.load_time_ms', notification.load_time * 1000)
end
def stop(notification)
@start_span.add_field('rspec.failed_count', notification.failed_examples.size)
@start_span.add_field('rspec.pending_count', notification.pending_examples.size)
@start_span.send
end
def start_dump(notification)
# puts "start_dump: #{notification}"
end
def example_group_started(notification)
@group_stack.push(group_span = Honeycomb.start_span(name: notification.group.description))
ENV['HTTP_X_HONEYCOMB_TRACE'] = group_span.to_trace_header unless ENV['HTTP_X_HONEYCOMB_TRACE']
group_span.add_field('rspec.type', 'group')
group_span.add_field('rspec.file_path', notification.group.file_path)
group_span.add_field('rspec.location', notification.group.location)
end
def example_group_finished(_notification)
group_span = @group_stack.pop
group_span.send
end
def example_started(notification)
@example_span = Honeycomb.start_span(name: 'unknown')
ENV['HTTP_X_HONEYCOMB_TRACE'] = @example_span.to_trace_header unless ENV['HTTP_X_HONEYCOMB_TRACE']
@example_span.add_field('rspec.type', 'example')
@example_span.add_field('rspec.file_path', notification.example.file_path)
@example_span.add_field('rspec.location', notification.example.location)
end
def example_passed(notification)
@example_span.add_field('rspec.result', 'passed')
@example_span.add_field('name', notification.example.description)
@example_span.add_field('rspec.description', notification.example.description)
@example_span.send
end
def example_failed(notification)
@example_span.add_field('rspec.result', 'failed')
@example_span.add_field('name', notification.example.description)
@example_span.add_field('rspec.description', notification.example.description)
@example_span.add_field('rspec.message', strip_ansi(notification.fully_formatted(0, RSpec::Core::Notifications::NullColorizer)))
@example_span.add_field('rspec.backtrace', notification.formatted_backtrace.join("\n"))
@example_span.send
end
def example_pending(notification)
@example_span.add_field('rspec.result', 'pending')
@example_span.add_field('name', notification.example.description)
@example_span.add_field('rspec.description', notification.example.description)
case notification
when RSpec::Core::Notifications::FailedExampleNotification
@example_span.add_field('rspec.message', strip_ansi(notification.fully_formatted(0, RSpec::Core::Notifications::NullColorizer)))
@example_span.add_field('rspec.backtrace', notification.formatted_backtrace.join("\n"))
when RSpec::Core::Notifications::SkippedExampleNotification
@example_span.add_field('rspec.message', strip_ansi(notification.fully_formatted(0, RSpec::Core::Notifications::NullColorizer)))
else
@example_span.add_field('rspec.result', notification.class)
end
@example_span.send
end
def seed(notification)
@start_span.add_field('rspec.seed', notification.seed) if notification.seed_used?
end
def message(notification)
# puts "message: #{notification}"
end
private
def strip_ansi(string)
string.gsub(%r{\e\[([\d;]+)m}, '')
end
end