Skip to content

Commit 21880fc

Browse files
authored
feat: improved karafka plugin for insights (#625)
* [feat] improved karafka events and metrics This implements a new Karafka subscriber that monitors more relevant events. The subscriber will then emit events and metrics where applicable. This also includes new configuration parameters that let you enable and disable Karafka specific Insights data. These are enabled by default. ``` karafka: insights: events: [boolean] # allow plugin to emit events from monitor metrics: [boolean] # allow plugin to emit metrics from monitor ``` * Pull error notifier out of listener * Add ability to configure via env * Add more to histogram payloads * Expand tags into proper keys * Fix * Add aggregated topic stats * Use underscores in metric names * Fix bug * Refactor * More refactoring * Also subscribe to producer errors * Use value keyword for all metric types * Simplify implementation and update specs * Fix some bugs and better uniformity to metrics code * Remove uncessary config * default values to 1 when not specified
1 parent 4f251b8 commit 21880fc

File tree

9 files changed

+431
-56
lines changed

9 files changed

+431
-56
lines changed

lib/honeybadger/config.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,20 @@ def load_plugin_insights?(name)
309309
!!self[:"#{name}.insights.enabled"]
310310
end
311311

312+
def load_plugin_insights_events?(name)
313+
return false unless insights_enabled?
314+
return false unless load_plugin_insights?(name)
315+
return true if self[:"#{name}.insights.events"].nil?
316+
!!self[:"#{name}.insights.events"]
317+
end
318+
319+
def load_plugin_insights_metrics?(name)
320+
return false unless insights_enabled?
321+
return false unless load_plugin_insights?(name)
322+
return true if self[:"#{name}.insights.metrics"].nil?
323+
!!self[:"#{name}.insights.metrics"]
324+
end
325+
312326
def root_regexp
313327
return @root_regexp if @root_regexp
314328
return nil if @no_root

lib/honeybadger/config/defaults.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,21 @@ class Boolean; end
363363
default: 60,
364364
type: Integer
365365
},
366+
:'karafka.insights.enabled' => {
367+
description: 'Enable automatic data collection for Karafka.',
368+
default: true,
369+
type: Boolean
370+
},
371+
:'karafka.insights.events' => {
372+
description: 'Enable automatic event capturing for Karafka.',
373+
default: true,
374+
type: Boolean
375+
},
376+
:'karafka.insights.metrics' => {
377+
description: 'Enable automatic metric data collection for Karafka.',
378+
default: true,
379+
type: Boolean
380+
},
366381
:'net_http.insights.enabled' => {
367382
description: 'Allow automatic instrumentation of Net::HTTP requests.',
368383
default: true,

lib/honeybadger/histogram.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,15 @@ def record(value)
99
return unless value
1010

1111
@samples += 1
12+
13+
@total ||= 0
14+
@total = @total + value
15+
16+
@min = value if @min.nil? || @min > value
17+
@max = value if @max.nil? || @max < value
18+
@avg = @total.to_f / @samples
19+
@latest = value
20+
1221
@bin_counts ||= Hash.new(0)
1322
@bin_counts[find_bin(value)] += 1
1423
end
@@ -25,6 +34,10 @@ def bins
2534

2635
def payloads
2736
[{
37+
min: @min,
38+
max: @max,
39+
avg: @avg,
40+
latest: @latest,
2841
bins: (bins + [INFINITY]).map { |bin| [bin.to_f, @bin_counts[bin]] }
2942
}]
3043
end

lib/honeybadger/instrumentation.rb

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -47,63 +47,91 @@ def monotonic_timer
4747
def time(name, *args)
4848
attributes = extract_attributes(args)
4949
callable = extract_callable(args)
50-
duration = attributes.delete(:duration)
50+
value = nil
5151

5252
if callable
53-
duration = monotonic_timer{ callable.call }[0]
53+
value = monotonic_timer{ callable.call }[0]
5454
elsif block_given?
55-
duration = monotonic_timer{ yield }[0]
55+
value = monotonic_timer{ yield }[0]
56+
else
57+
value = attributes.delete(:duration) || attributes.delete(:value)
5658
end
5759

58-
raise 'No duration found' if duration.nil?
60+
raise 'No value found' if value.nil?
5961

6062
Honeybadger::Timer.register(registry, name, attributes).tap do |timer|
61-
timer.record(duration)
63+
timer.record(value)
6264
end
6365
end
6466

6567
def histogram(name, *args)
6668
attributes = extract_attributes(args)
6769
callable = extract_callable(args)
68-
duration = attributes.delete(:duration)
70+
value = nil
6971

7072
if callable
71-
duration = monotonic_timer{ callable.call }[0]
73+
value = monotonic_timer{ callable.call }[0]
7274
elsif block_given?
73-
duration = monotonic_timer{ yield }[0]
75+
value = monotonic_timer{ yield }[0]
76+
else
77+
value = attributes.delete(:duration) || attributes.delete(:value)
7478
end
7579

76-
raise 'No duration found' if duration.nil?
80+
raise 'No value found' if value.nil?
7781

7882
Honeybadger::Histogram.register(registry, name, attributes).tap do |histogram|
79-
histogram.record(duration)
83+
histogram.record(value)
8084
end
8185
end
8286

8387
def increment_counter(name, *args)
8488
attributes = extract_attributes(args)
85-
by = extract_callable(args)&.call || attributes.delete(:by) || 1
86-
by = yield if block_given?
89+
callable = extract_callable(args)
90+
value = nil
91+
92+
if callable
93+
value = callable.call
94+
elsif block_given?
95+
value = yield
96+
else
97+
value = attributes.delete(:by) || attributes.delete(:value) || 1
98+
end
8799

88100
Honeybadger::Counter.register(registry, name, attributes).tap do |counter|
89-
counter.count(by)
101+
counter.count(value)
90102
end
91103
end
92104

93105
def decrement_counter(name, *args)
94106
attributes = extract_attributes(args)
95-
by = extract_callable(args)&.call || attributes.delete(:by) || 1
96-
by = yield if block_given?
107+
callable = extract_callable(args)
108+
value = nil
109+
110+
if callable
111+
value = callable.call
112+
elsif block_given?
113+
value = yield
114+
else
115+
value = attributes.delete(:by) || attributes.delete(:value) || 1
116+
end
97117

98118
Honeybadger::Counter.register(registry, name, attributes).tap do |counter|
99-
counter.count(by * -1)
119+
counter.count(value * -1)
100120
end
101121
end
102122

103123
def gauge(name, *args)
104124
attributes = extract_attributes(args)
105-
value = extract_callable(args)&.call || attributes.delete(:value)
106-
value = yield if block_given?
125+
callable = extract_callable(args)
126+
value = nil
127+
128+
if callable
129+
value = callable.call
130+
elsif block_given?
131+
value = yield
132+
else
133+
value = attributes.delete(:value)
134+
end
107135

108136
Honeybadger::Gauge.register(registry, name, attributes).tap do |gauge|
109137
gauge.record(value)

lib/honeybadger/instrumentation_helper.rb

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def time(name, *args)
5656
metric_instrumentation.time(name, attributes, ->{ callable.call })
5757
elsif block_given?
5858
metric_instrumentation.time(name, attributes, ->{ yield })
59-
elsif attributes.keys.include?(:duration)
59+
else
6060
metric_instrumentation.time(name, attributes)
6161
end
6262
end
@@ -68,38 +68,44 @@ def histogram(name, *args)
6868
metric_instrumentation.histogram(name, attributes, ->{ callable.call })
6969
elsif block_given?
7070
metric_instrumentation.histogram(name, attributes, ->{ yield })
71-
elsif attributes.keys.include?(:duration)
71+
else
7272
metric_instrumentation.histogram(name, attributes)
7373
end
7474
end
7575

7676
def increment_counter(name, *args)
7777
attributes = extract_attributes(args)
78-
by = extract_callable(args)&.call || attributes.delete(:by) || 1
79-
if block_given?
78+
callable = extract_callable(args)
79+
if callable
80+
metric_instrumentation.increment_counter(name, attributes, ->{ callable.call })
81+
elsif block_given?
8082
metric_instrumentation.increment_counter(name, attributes, ->{ yield })
8183
else
82-
metric_instrumentation.increment_counter(name, attributes.merge(by: by))
84+
metric_instrumentation.increment_counter(name, attributes)
8385
end
8486
end
8587

8688
def decrement_counter(name, *args)
8789
attributes = extract_attributes(args)
88-
by = extract_callable(args)&.call || attributes.delete(:by) || 1
89-
if block_given?
90+
callable = extract_callable(args)
91+
if callable
92+
metric_instrumentation.decrement_counter(name, attributes, ->{ callable.call })
93+
elsif block_given?
9094
metric_instrumentation.decrement_counter(name, attributes, ->{ yield })
9195
else
92-
metric_instrumentation.decrement_counter(name, attributes.merge(by: by))
96+
metric_instrumentation.decrement_counter(name, attributes)
9397
end
9498
end
9599

96100
def gauge(name, *args)
97101
attributes = extract_attributes(args)
98-
value = extract_callable(args)&.call || attributes.delete(:value)
99-
if block_given?
102+
callable = extract_callable(args)
103+
if callable
104+
metric_instrumentation.gauge(name, attributes, ->{ callable.call })
105+
elsif block_given?
100106
metric_instrumentation.gauge(name, attributes, ->{ yield })
101107
else
102-
metric_instrumentation.gauge(name, attributes.merge(value: value))
108+
metric_instrumentation.gauge(name, attributes)
103109
end
104110
end
105111

0 commit comments

Comments
 (0)