gitlab-labkit 1.3.4 → 1.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: a29bc2351fbe292697c582547316e370a7320826be10ecb9ef26580b1d5d3dce
4
- data.tar.gz: f489a1fdd02e6a8ba3750c93bcab4baaa4907983abcaf81544e3ec300234a88e
3
+ metadata.gz: fef9aed12ba67f4628dcddf7273d14a420325935afe77dfad8950a57b2a28bf8
4
+ data.tar.gz: 4cd67209a2a395f1e0b2e0b866a3df8d266a4bb3390f14de24336265e78d88bd
5
5
  SHA512:
6
- metadata.gz: f5b4397587a97aa9aadb2b8b4606c675337110ab65d410f211d0c33a0e89fc6b4c2b68f8d07d78906ccd680e31612439d4b316ba955b770a7074582d6b7f80e4
7
- data.tar.gz: 521c43e11ede3e207218574c00b5644f2907deb19d876213c862818c0e3c12ff65f1eaeaa4c6b9b1afeb0a59f9d20a67552c7a8a7d8dbb48997d9cc7d55d30ac
6
+ metadata.gz: d672a393f0491b986882ecedc0d80ebff33bc266a2eb34f407cc1158b1ba3c19e419fcac64ce0b86d59eb039da16cc57fd937f69eb88529deb014dfc4c587566
7
+ data.tar.gz: bac5642a671b7a86ed7b375273fe9fa3aa76335ac1718ece9104017104e639ad86e16d3361d8721ddb39ddea94628a8d7a990a63adc17ca63263083397c0f815
data/lib/gitlab-labkit.rb CHANGED
@@ -10,6 +10,7 @@ module Labkit
10
10
  autoload :Context, "labkit/context"
11
11
  autoload :Correlation, "labkit/correlation"
12
12
  autoload :CoveredExperience, "labkit/user_experience_sli" # Backward compatibility alias
13
+ autoload :ApplicationSli, "labkit/application_sli"
13
14
  autoload :UserExperienceSli, "labkit/user_experience_sli"
14
15
  autoload :FIPS, "labkit/fips"
15
16
  autoload :Tracing, "labkit/tracing"
@@ -0,0 +1,69 @@
1
+ # Application SLIs
2
+
3
+ This module provides [Application Service Level Indicators(SLIs)](https://docs.gitlab.com/development/application_slis/)
4
+ for monitoring and observability. It allows defining SLIs directly in Ruby code, keeping the definition of operations and their success close to the implementation.
5
+
6
+ Two SLI types are available:
7
+
8
+ - **`Labkit::ApplicationSli::Apdex`** - Measures the performance of successful operations using a success rate.
9
+ - **`Labkit::ApplicationSli::ErrorRate`** - Measures the rate of unsuccessful operations using an error rate.
10
+
11
+ ## Defining a new SLI
12
+
13
+ When you define an SLI, two [Prometheus counters](https://prometheus.io/docs/concepts/metric_types/#counter) are emitted. Both contain a total operation count, and a numerator counter for the success or error rate.
14
+
15
+ `Labkit::ApplicationSli::Apdex` defines:
16
+
17
+ - `gitlab_sli_<name>_apdex_total` - total number of measurements
18
+ - `gitlab_sli_<name>_apdex_success_total` - number of successful measurements
19
+
20
+ `Labkit::ApplicationSli::ErrorRate` defines:
21
+
22
+ - `gitlab_sli_<name>_total` - total number of measurements
23
+ - `gitlab_sli_<name>_error_total` - number of error measurements
24
+
25
+ ## Initializing an SLI
26
+
27
+ Before the first Prometheus scrape, initialize the SLI with all possible label combinations to [avoid missing metrics](https://prometheus.io/docs/practices/instrumentation/#avoid-missing-metrics):
28
+
29
+ ```ruby
30
+ Labkit::ApplicationSli::Apdex.initialize_sli(:received_email, [
31
+ {
32
+ feature_category: :team_planning,
33
+ email_type: :create_issue
34
+ },
35
+ {
36
+ feature_category: :service_desk,
37
+ email_type: :service_desk
38
+ }
39
+ ])
40
+ ```
41
+
42
+ ## Tracking operations
43
+
44
+ Increment the SLI counters using the `#increment` method with the appropriate labels.
45
+
46
+ For `Apdex`, pass `success:` to indicate whether the operation met the performance target:
47
+
48
+ ```ruby
49
+ Labkit::ApplicationSli::Apdex[:received_email].increment(
50
+ labels: {
51
+ feature_category: :service_desk,
52
+ email_type: :service_desk
53
+ },
54
+ success: issue_created?
55
+ )
56
+ ```
57
+
58
+ For `ErrorRate`, pass `error:` to indicate whether the operation failed:
59
+
60
+ ```ruby
61
+ Labkit::ApplicationSli::ErrorRate[:merge].increment(
62
+ labels: {
63
+ merge_type: :fast_forward
64
+ },
65
+ error: !merge_success?
66
+ )
67
+ ```
68
+
69
+ When `success:` (or `error:`) is truthy, both the total and numerator counters are incremented. When falsy, only the total counter is incremented.
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Labkit
4
+ module ApplicationSli
5
+ class Apdex
6
+ include Labkit::ApplicationSli
7
+
8
+ def increment(labels:, success:)
9
+ super(labels: labels, increment_numerator: success)
10
+ end
11
+
12
+ private
13
+
14
+ def counter_name(suffix)
15
+ :"#{COUNTER_PREFIX}_#{name}_apdex_#{suffix}"
16
+ end
17
+
18
+ def numerator_counter
19
+ prometheus.counter(counter_name('success_total'), "Number of successful measurements for #{name}")
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Labkit
4
+ module ApplicationSli
5
+ class ErrorRate
6
+ include Labkit::ApplicationSli
7
+
8
+ def increment(labels:, error:)
9
+ super(labels: labels, increment_numerator: error)
10
+ end
11
+
12
+ private
13
+
14
+ def counter_name(suffix)
15
+ :"#{COUNTER_PREFIX}_#{name}_#{suffix}"
16
+ end
17
+
18
+ def numerator_counter
19
+ prometheus.counter(counter_name('error_total'), "Number of error measurements for #{name}")
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Labkit
4
+ module ApplicationSli
5
+ COUNTER_PREFIX = 'gitlab_sli'
6
+
7
+ module ClassMethods
8
+ INITIALIZATION_MUTEX = Mutex.new
9
+
10
+ def [](name)
11
+ known_slis[name] || initialize_sli(name, [])
12
+ end
13
+
14
+ def initialize_sli(name, possible_label_combinations)
15
+ INITIALIZATION_MUTEX.synchronize do
16
+ next known_slis[name] if initialized?(name)
17
+
18
+ sli = new(name)
19
+ sli.initialize_counters(possible_label_combinations)
20
+ known_slis[name] = sli
21
+ end
22
+ end
23
+
24
+ def initialized?(name)
25
+ known_slis.key?(name) && known_slis[name].initialized?
26
+ end
27
+
28
+ private
29
+
30
+ def known_slis
31
+ @known_slis ||= {}
32
+ end
33
+ end
34
+
35
+ def self.included(mod)
36
+ mod.extend(ClassMethods)
37
+ end
38
+
39
+ attr_reader :name
40
+
41
+ def initialize(name)
42
+ @name = name
43
+ @initialized_with_combinations = false
44
+ end
45
+
46
+ def initialize_counters(possible_label_combinations)
47
+ @initialized_with_combinations = possible_label_combinations.any?
48
+ possible_label_combinations.each do |label_combination|
49
+ total_counter.get(label_combination)
50
+ numerator_counter.get(label_combination)
51
+ end
52
+ end
53
+
54
+ def increment(labels:, increment_numerator:)
55
+ total_counter.increment(labels)
56
+ numerator_counter.increment(labels) if increment_numerator
57
+ end
58
+
59
+ def initialized?
60
+ @initialized_with_combinations
61
+ end
62
+
63
+ private
64
+
65
+ def total_counter
66
+ prometheus.counter(counter_name('total'), "Total number of measurements for #{name}")
67
+ end
68
+
69
+ def prometheus
70
+ Labkit::Metrics::Client
71
+ end
72
+
73
+ autoload :Apdex, "labkit/application_sli/apdex"
74
+ autoload :ErrorRate, "labkit/application_sli/error_rate"
75
+ end
76
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gitlab-labkit
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.4
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Newdigate
@@ -487,6 +487,10 @@ files:
487
487
  - exe/labkit-logging
488
488
  - gitlab-labkit.gemspec
489
489
  - lib/gitlab-labkit.rb
490
+ - lib/labkit/application_sli.rb
491
+ - lib/labkit/application_sli/README.md
492
+ - lib/labkit/application_sli/apdex.rb
493
+ - lib/labkit/application_sli/error_rate.rb
490
494
  - lib/labkit/context.rb
491
495
  - lib/labkit/correlation.rb
492
496
  - lib/labkit/correlation/correlation_id.rb