twingly-metrics 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: be11bd1a0f91edf2ac37637732b5ed9452d9ac959354c7cd4cb2dac448e00939
4
- data.tar.gz: 4f4aa1606534e1a67ddacdc5058a737733ca0be788af51fa91fb807d7cac8e3c
3
+ metadata.gz: db46b25f0b710bb60e8b504902a79718e2828b067badaeb9690f90516f4e6324
4
+ data.tar.gz: 99b630dbcbb6da1830cd2b7605f89dcaef1fcf0d95108370bad2c651aa9249bc
5
5
  SHA512:
6
- metadata.gz: cb94deb9dc0274ec9400662f84b93a857fc43d15d39d6c6bcd2ff57c7b2a0a11da6fb1923283537c44fc33ce135464b9788a615a4c6a97a9c670832004471e1d
7
- data.tar.gz: df1823f5e97aa1c08d1fdca1ab4e8d30d9620881aa0facbafbe700218f5d1d4bac6e79ee2ba50c436abbce5fa22e1c3499ef00bb30c660db80daf4720f132463
6
+ metadata.gz: 31463227adeae2852358eea87082bc69cdc7692cece9935c13bccb68f6ce19f87470f0d75bd330e2d4b7eecc2e9f86b3138d9e10e3fb1b9fdafd173ce45af8ff
7
+ data.tar.gz: 2d557c902b80cb79a78b1a64c35191eb4261919e66d9f5f4faef84cf24b9a684b9e3becbde33cc7f00d8894d97c4265e9a4cd11b2799f8d0e52a05a000462cc8
data/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  A gem for collecting and reporting metrics from our Ruby applications.
6
6
 
7
- This gem currently relies on the [`metriks` gem][metriks] for collecting metrics. The reason for this is that we're already using that gem in our projects. What the `twingly-metrics` gem currently adds in functionality, is the ability to report metrics to [Grafana cloud][grafana-cloud], using their [Graphite HTTP API][grafana-cloud-graphite-api].
7
+ This gem currently relies on the [`metriks` gem][metriks] for collecting metrics. The reason for this is that we're already using that gem in our projects. What the `twingly-metrics` gem currently adds in functionality, is the ability to report metrics to [Grafana cloud][grafana-cloud], using their [Graphite HTTP API][grafana-cloud-graphite-api], along with some convenience methods for working with metrics.
8
8
 
9
9
  The code here was inspired by the reporter in the [`metriks-librato_metrics` gem][metriks-librato_metrics].
10
10
 
@@ -50,21 +50,41 @@ reporter = Twingly::Metrics::GrafanaCloudReporter.new(
50
50
  reporter.start # Starts the reporter thread in the background
51
51
 
52
52
  # Create some metrics for the reporter to have something to report
53
- Metriks.meter("test.meter").mark(1)
53
+ Twingly::Metrics.meter("test.meter").mark(1)
54
54
 
55
55
  at_exit do
56
56
  reporter.flush # Ensure all unreported metrics are sent before exiting
57
57
  end
58
58
  ```
59
59
 
60
+ The `endpoint`, `user`, and `token` options can also be configured by setting the following environment variables:
61
+
62
+ ```
63
+ GRAFANA_METRICS_ENDPOINT=
64
+ GRAFANA_METRICS_USER=
65
+ GRAFANA_METRICS_TOKEN=
66
+ ```
67
+
68
+ *Note: If the environment variables are not set, or the corresponding parameters are not provided, the reporter will not try to report any metrics to Grafana.*
69
+
60
70
  ### Supported metric types
61
71
 
62
72
  The reporter currently supports the following metric types from the `metriks` gem:
63
73
 
64
- * [`Metriks.counter`](https://github.com/eric/metriks?tab=readme-ov-file#counters)
65
- * [`Metriks.gauge`](https://github.com/eric/metriks?tab=readme-ov-file#gauges)
66
- * [`Metriks.meter`](https://github.com/eric/metriks?tab=readme-ov-file#meters)
67
- * [`Metriks.timer`](https://github.com/eric/metriks?tab=readme-ov-file#timers)
74
+ * `Twingly::Metrics.counter` - See [`Metriks.counter`](https://github.com/eric/metriks?tab=readme-ov-file#counters)
75
+ * `Twingly::Metrics.gauge` - See [`Metriks.gauge`](https://github.com/eric/metriks?tab=readme-ov-file#gauges)
76
+ * `Twingly::Metrics.meter` - See [`Metriks.meter`](https://github.com/eric/metriks?tab=readme-ov-file#meters)
77
+ * `Twingly::Metrics.timer` - See [`Metriks.timer`](https://github.com/eric/metriks?tab=readme-ov-file#timers)
78
+
79
+ Helper methods are also provided for some common use cases:
80
+
81
+ ```ruby
82
+ # Equivalent to Twingly::Metrics.meter("my_meter").mark(1)
83
+ Twingly::Metrics.mark("my_meter", 1)
84
+
85
+ # Equivalent to Twingly::Metrics.timer("my_timer").time { ... }
86
+ Twingly::Metrics.time("my_timer") { ... }
87
+ ```
68
88
 
69
89
  [metriks]: https://github.com/eric/metriks
70
90
  [grafana-cloud]: https://grafana.com/products/cloud/
@@ -44,15 +44,17 @@ module Twingly
44
44
  attr_reader :interval
45
45
  attr_reader :timeout
46
46
 
47
- def initialize(endpoint:, user:, token:, **options) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity
48
- @endpoint = endpoint
49
- @user = user
50
- @token = token
47
+ def initialize(endpoint: nil, user: nil, token: nil, **options) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
48
+ @endpoint = endpoint || ENV.fetch("GRAFANA_METRICS_ENDPOINT") { nil }
49
+ @user = user || ENV.fetch("GRAFANA_METRICS_USER") { nil }
50
+ @token = token || ENV.fetch("GRAFANA_METRICS_TOKEN") { nil }
51
51
 
52
52
  @prefix = options[:prefix]
53
53
  @source = options[:source] || default_source
54
54
  @logger = options[:logger]
55
55
 
56
+ log_missing_credentials unless credentials_provided?
57
+
56
58
  @registry = options[:registry] || Metriks::Registry.default
57
59
  @interval = options[:interval] || 60
58
60
  @on_error = options[:on_error] || proc { |ex| @logger&.error(ex) }
@@ -69,7 +71,8 @@ module Twingly
69
71
  @reporter_thread = nil
70
72
  end
71
73
 
72
- def start
74
+ def start # rubocop:disable Metrics/MethodLength
75
+ return unless credentials_provided?
73
76
  return if @reporter_thread&.alive?
74
77
 
75
78
  @running = true
@@ -85,6 +88,8 @@ module Twingly
85
88
  end
86
89
 
87
90
  def stop
91
+ return unless credentials_provided?
92
+
88
93
  @running = false
89
94
 
90
95
  return unless @reporter_thread
@@ -99,10 +104,14 @@ module Twingly
99
104
  end
100
105
 
101
106
  def flush
107
+ return unless credentials_provided?
108
+
102
109
  @flush_metrics_mutex.synchronize do
103
110
  request_data = build_metrics_data_for_request
104
111
 
105
- make_request(request_data)
112
+ retry_failing_request do
113
+ make_request(request_data)
114
+ end
106
115
  end
107
116
  rescue StandardError => e
108
117
  @on_error.call(e)
@@ -144,6 +153,24 @@ module Twingly
144
153
  end
145
154
  end
146
155
 
156
+ def retry_failing_request(max_retries: 3)
157
+ retries = 0
158
+
159
+ begin
160
+ yield
161
+ rescue RequestFailedError => e
162
+ retries += 1
163
+
164
+ raise if retries > max_retries
165
+
166
+ @logger&.debug("GrafanaCloudReporter: Request failed, retrying (#{retries}/#{max_retries}) - #{e.message}")
167
+
168
+ sleep 1
169
+
170
+ retry
171
+ end
172
+ end
173
+
147
174
  def build_metrics_data_for_request
148
175
  time = now_floored
149
176
 
@@ -247,6 +274,16 @@ module Twingly
247
274
  @next_time = now if @next_time <= now
248
275
  @next_time += @interval - (@next_time % @interval)
249
276
  end
277
+
278
+ def credentials_provided?
279
+ @endpoint && @user && @token
280
+ end
281
+
282
+ def log_missing_credentials
283
+ return unless @logger
284
+
285
+ @logger.warn("#{self.class.name}: Metrics won't be reported, as endpoint, user, or token is missing.")
286
+ end
250
287
  end
251
288
  end
252
289
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Twingly
4
4
  module Metrics
5
- VERSION = "0.2.0"
5
+ VERSION = "0.4.0"
6
6
  end
7
7
  end
@@ -1,4 +1,36 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "metriks"
4
+
3
5
  require_relative "metrics/version"
4
6
  require_relative "metrics/grafana_cloud_reporter"
7
+
8
+ module Twingly
9
+ module Metrics
10
+ def self.counter(name)
11
+ Metriks.counter(name)
12
+ end
13
+
14
+ def self.gauge(name, callable = nil, &block)
15
+ Metriks.gauge(name, callable, &block)
16
+ end
17
+
18
+ def self.timer(name)
19
+ Metriks.timer(name)
20
+ end
21
+
22
+ def self.meter(name)
23
+ Metriks.meter(name)
24
+ end
25
+
26
+ def self.mark(name, val = 1)
27
+ meter(name).mark(val)
28
+ end
29
+
30
+ def self.time(name, duration = nil, &block)
31
+ return timer(name).update(duration) if duration
32
+
33
+ timer(name).time(&block)
34
+ end
35
+ end
36
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: twingly-metrics
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Twingly AB
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-07-21 00:00:00.000000000 Z
10
+ date: 2025-09-03 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: metriks