event_tracer 0.5.1 → 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3c2e5bbf4d4546e3ece6589508e00fc01eb30ca41b572ff2afbb4185b73c93d5
4
- data.tar.gz: e3fe3b13cf8fc1e43732a75386502618427cab7a449fe95b8d2c69789383947b
3
+ metadata.gz: 77541537838df5e2de191b30cac6096e30ef9afbba5634c99ab7dceca8378f80
4
+ data.tar.gz: ce9067501e85318e4b22d731d9e28472e11b4142d70ff4d4e6b3049c5d5daf35
5
5
  SHA512:
6
- metadata.gz: 17cd02fe83f7725b8e2a9d495979f5b183e2a63fc071b1b58795adfb910ed0c9048f1692b608d78d0348377b4c9216c1601481234ff60791206b2c1797e7d51f
7
- data.tar.gz: ba23fdd140689fa467671a1f28024f38ea6b5c9e1ddd911c4980cbb91d57faf7a5ad2ce028aaffcead4f75d06ac4d5e30b0728525a3dac074ac366b8318f2797
6
+ metadata.gz: 3980aee7c87f0e4b7aaad10def59b2a2d7cf6aa9facad6a34193dd453048c428c0553c735fae7294376ed44e574c3371854e56eb36ec77197094a96a55945354
7
+ data.tar.gz: 816e02c8bddc0444fba2f8e189789c887ef2f82fc3a76618af2ed56145b249a64f4f3a5ddbba7d0fc319b8da976a72a1cd897033046849549d775b7d5498ca33
@@ -1,4 +1,4 @@
1
- require_relative './basic_decorator'
1
+ require_relative './metric_logger'
2
2
 
3
3
  # NOTES
4
4
  # Appsignal interface to send our usual actions
@@ -10,55 +10,32 @@ require_relative './basic_decorator'
10
10
  # appsignal_logger.info metrics: [:counter_1, :counter_2]
11
11
  # appsignal_logger.info metrics: { counter_1: { type: :counter, value: 1 }, gauce_2: { type: :gauce, value: 10 } }
12
12
  module EventTracer
13
- class AppsignalLogger < BasicDecorator
13
+ class AppsignalLogger < MetricLogger
14
14
 
15
15
  SUPPORTED_METRIC_TYPES = {
16
16
  counter: :increment_counter,
17
17
  distribution: :add_distribution_value,
18
18
  gauge: :set_gauge
19
- }
19
+ }.freeze
20
20
  DEFAULT_METRIC_TYPE = :increment_counter
21
21
  DEFAULT_COUNTER = 1
22
22
 
23
- attr_reader :allowed_tags
24
-
25
23
  def initialize(decoratee, allowed_tags: [])
26
24
  super(decoratee)
27
25
  @allowed_tags = allowed_tags.freeze
28
26
  end
29
27
 
30
- LOG_TYPES.each do |log_type|
31
- define_method log_type do |**args|
32
- metrics = args[:metrics]
33
-
34
- return fail_result('Invalid appsignal config') unless valid_args?(metrics)
35
- return success_result if metrics.empty?
36
-
37
- tags = args.slice(*allowed_tags)
38
-
39
- case metrics
40
- when Array
41
- metrics.each do |metric|
42
- appsignal.public_send(DEFAULT_METRIC_TYPE, metric, DEFAULT_COUNTER, tags)
43
- end
44
- when Hash
45
- metrics.each do |metric_name, metric_payload|
46
- payload = metric_payload.transform_keys(&:to_sym)
47
- metric_type = SUPPORTED_METRIC_TYPES[payload.fetch(:type).to_sym]
48
- appsignal.public_send(metric_type, metric_name, payload.fetch(:value), tags) if metric_type
49
- end
50
- end
28
+ private
51
29
 
52
- success_result
30
+ def send_metric(metric_type, metric_name, value, tags)
31
+ appsignal.public_send(metric_type, metric_name, value, tags)
53
32
  end
54
- end
55
33
 
56
- private
34
+ def build_tags(args)
35
+ args.slice(*allowed_tags)
36
+ end
57
37
 
58
38
  alias_method :appsignal, :decoratee
59
39
 
60
- def valid_args?(metrics)
61
- metrics && (metrics.is_a?(Hash) || metrics.is_a?(Array))
62
- end
63
40
  end
64
41
  end
@@ -58,8 +58,15 @@ module EventTracer
58
58
  attr_reader :buffer_size, :flush_interval, :buffer
59
59
 
60
60
  def add_item?
61
- buffer.size < buffer_size &&
62
- (buffer.empty? || buffer.first[:created_at] > Time.now - flush_interval)
61
+ return false if buffer.size >= buffer_size
62
+
63
+ # NOTE: we cannot use buffer.empty? then buffer.first here
64
+ # due to race-condition when another thread flushes the buffer
65
+ # right after buffer.empty? but before buffer.first is called.
66
+ # If we have more complicated use case, we may need to start introducing
67
+ # mutext.
68
+ first_item = buffer.first
69
+ first_item.nil? || first_item[:created_at] > Time.now - flush_interval
63
70
  end
64
71
  end
65
72
  end
@@ -1,4 +1,5 @@
1
- require_relative './basic_decorator'
1
+ require_relative './metric_logger'
2
+
2
3
  # NOTES
3
4
  # Datadog interface to send our usual actions
4
5
  # BasicDecorator adds a transparent interface on top of the datadog interface
@@ -10,7 +11,7 @@ require_relative './basic_decorator'
10
11
  # data_dog_logger.info metrics: { counter_1: { type: :counter, value: 1}, gauce_2: { type: :gauce, value: 10 } }
11
12
 
12
13
  module EventTracer
13
- class DatadogLogger < BasicDecorator
14
+ class DatadogLogger < MetricLogger
14
15
 
15
16
  SUPPORTED_METRIC_TYPES = {
16
17
  counter: :count,
@@ -22,52 +23,22 @@ module EventTracer
22
23
  DEFAULT_METRIC_TYPE = :count
23
24
  DEFAULT_COUNTER = 1
24
25
 
25
- attr_reader :allowed_tags
26
-
27
26
  def initialize(decoratee, allowed_tags: [], default_tags: {})
28
27
  super(decoratee)
29
28
  @allowed_tags = allowed_tags.freeze
30
29
  @default_tags = default_tags.freeze
31
30
  end
32
31
 
33
- LOG_TYPES.each do |log_type|
34
- define_method log_type do |**args|
35
- metrics = args[:metrics]
36
-
37
- return fail_result('Invalid Datadog config') unless valid_args?(metrics)
38
- return success_result if metrics.empty?
39
-
40
- tags = build_tags(args)
41
-
42
- case metrics
43
- when Array
44
- metrics.each do |metric|
45
- datadog.public_send(DEFAULT_METRIC_TYPE, metric, DEFAULT_COUNTER, tags: tags)
46
- end
47
- when Hash
48
- metrics.each do |metric_name, metric_payload|
49
- payload = metric_payload.transform_keys(&:to_sym)
50
- metric_type = SUPPORTED_METRIC_TYPES[payload.fetch(:type).to_sym]
51
- datadog.public_send(metric_type, metric_name, payload.fetch(:value), tags: tags) if metric_type
52
- end
53
- end
32
+ private
54
33
 
55
- success_result
56
- end
34
+ def send_metric(metric_type, metric_name, value, tags)
35
+ datadog.public_send(metric_type, metric_name, value, tags: tags)
57
36
  end
58
37
 
59
- private
60
-
61
38
  alias_method :datadog, :decoratee
62
39
 
63
- attr_reader :default_tags
64
-
65
- def valid_args?(metrics)
66
- metrics && (metrics.is_a?(Hash) || metrics.is_a?(Array))
67
- end
68
-
69
40
  def build_tags(args)
70
- @default_tags.merge(args.slice(*allowed_tags)).map do |tag, value|
41
+ default_tags.merge(args.slice(*allowed_tags)).map do |tag, value|
71
42
  "#{tag}:#{value}"
72
43
  end
73
44
  end
@@ -0,0 +1,42 @@
1
+ require_relative './basic_decorator'
2
+
3
+ module EventTracer
4
+ class MetricLogger < BasicDecorator
5
+
6
+ attr_reader :allowed_tags
7
+
8
+ LOG_TYPES.each do |log_type|
9
+ define_method log_type do |**args|
10
+ metrics = args[:metrics]
11
+
12
+ return fail_result("Invalid metrics for #{self.class.name}") unless valid_args?(metrics)
13
+ return success_result if metrics.empty?
14
+
15
+ tags = build_tags(args)
16
+
17
+ case metrics
18
+ when Array
19
+ metrics.each do |metric|
20
+ send_metric(self.class::DEFAULT_METRIC_TYPE, metric, self.class::DEFAULT_COUNTER, tags)
21
+ end
22
+ when Hash
23
+ metrics.each do |metric_name, metric_payload|
24
+ payload = metric_payload.transform_keys(&:to_sym)
25
+ metric_type = self.class::SUPPORTED_METRIC_TYPES[payload.fetch(:type).to_sym]
26
+ send_metric(metric_type, metric_name, payload.fetch(:value), tags) if metric_type
27
+ end
28
+ end
29
+
30
+ success_result
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ attr_reader :default_tags
37
+
38
+ def valid_args?(metrics)
39
+ metrics && (metrics.is_a?(Hash) || metrics.is_a?(Array))
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,64 @@
1
+ require_relative './metric_logger'
2
+
3
+ module EventTracer
4
+ class PrometheusLogger < MetricLogger
5
+
6
+ SUPPORTED_METRIC_TYPES = {
7
+ counter: :increment_count,
8
+ gauge: :set_gauge
9
+ }.freeze
10
+ DEFAULT_METRIC_TYPE = :increment_count
11
+ DEFAULT_COUNTER = 1
12
+
13
+ def initialize(prometheus, allowed_tags: [], default_tags: {}, raise_if_missing: true)
14
+ super(prometheus)
15
+ @allowed_tags = allowed_tags.freeze
16
+ @default_tags = default_tags.freeze
17
+ @raise_if_missing = raise_if_missing
18
+ end
19
+
20
+ private
21
+
22
+ def send_metric(metric_type, metric_name, value, labels)
23
+ send(metric_type, metric_name, value, labels: labels)
24
+ end
25
+
26
+ alias_method :prometheus, :decoratee
27
+
28
+ attr_reader :raise_if_missing
29
+
30
+ def increment_count(metric_name, value, labels:)
31
+ metric = get_metric(metric_name.to_sym, :counter)
32
+ metric.increment(by: value, labels: labels)
33
+ end
34
+
35
+ def set_gauge(metric_name, value, labels:)
36
+ metric = get_metric(metric_name.to_sym, :gauge)
37
+ metric.set(value, labels: labels)
38
+ end
39
+
40
+ def get_metric(metric_name, metric_type)
41
+ metric = prometheus.get(metric_name)
42
+
43
+ return metric if metric
44
+ raise "Metric #{metric_name} not registered" if raise_if_missing
45
+
46
+ prometheus.public_send(
47
+ metric_type,
48
+ metric_name,
49
+ docstring: "A #{metric_type} for #{metric_name}",
50
+ labels: labels_for_registration
51
+ )
52
+ end
53
+
54
+ def build_tags(args)
55
+ allowed_tags.inject(default_tags) do |metric_labels, tag|
56
+ metric_labels.merge(tag => args[tag])
57
+ end
58
+ end
59
+
60
+ def labels_for_registration
61
+ (allowed_tags + default_tags.keys).uniq
62
+ end
63
+ end
64
+ end
@@ -1,3 +1,3 @@
1
1
  module EventTracer
2
- VERSION = '0.5.1'.freeze
2
+ VERSION = '0.6.2'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: event_tracer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - melvrickgoh
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-05-18 00:00:00.000000000 Z
11
+ date: 2022-06-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -102,6 +102,8 @@ files:
102
102
  - lib/event_tracer/dynamo_db/worker.rb
103
103
  - lib/event_tracer/error_with_payload.rb
104
104
  - lib/event_tracer/log_result.rb
105
+ - lib/event_tracer/metric_logger.rb
106
+ - lib/event_tracer/prometheus_logger.rb
105
107
  - lib/event_tracer/version.rb
106
108
  homepage: https://github.com/melvrickgoh/event_tracer
107
109
  licenses: