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 +4 -4
- data/README.md +26 -6
- data/lib/twingly/metrics/grafana_cloud_reporter.rb +43 -6
- data/lib/twingly/metrics/version.rb +1 -1
- data/lib/twingly/metrics.rb +32 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: db46b25f0b710bb60e8b504902a79718e2828b067badaeb9690f90516f4e6324
|
4
|
+
data.tar.gz: 99b630dbcbb6da1830cd2b7605f89dcaef1fcf0d95108370bad2c651aa9249bc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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
|
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
|
-
|
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
|
data/lib/twingly/metrics.rb
CHANGED
@@ -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.
|
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-
|
10
|
+
date: 2025-09-03 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: metriks
|