gitlab-labkit 1.3.3 → 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: fd5d320e1c751f2fea87cb55e57c3353b1255c62a126e97eba24a60642c9e0e0
4
- data.tar.gz: 543e2fcd663bf562cb23426f0903acbafcf7f2edb6738e12dcc420fdfd8e26aa
3
+ metadata.gz: fef9aed12ba67f4628dcddf7273d14a420325935afe77dfad8950a57b2a28bf8
4
+ data.tar.gz: 4cd67209a2a395f1e0b2e0b866a3df8d266a4bb3390f14de24336265e78d88bd
5
5
  SHA512:
6
- metadata.gz: af194fc50ac69e6136c8e849b3445ed8f99c53eb555745ef5c03cbc5f42fde12b0a8fa33bb402c1fc80895feb4e9fba4a5c49cf345c77be10cc977f92cb105c4
7
- data.tar.gz: e0b1dd39d3002edd45eb722d0aebe86e800688d878ab5e3beb79d060f65d7a3637ef3d5fb6351b9d80d81156542dd25dc0e3c291c4b7ce0485a4114752e69644
6
+ metadata.gz: d672a393f0491b986882ecedc0d80ebff33bc266a2eb34f407cc1158b1ba3c19e419fcac64ce0b86d59eb039da16cc57fd937f69eb88529deb014dfc4c587566
7
+ data.tar.gz: bac5642a671b7a86ed7b375273fe9fa3aa76335ac1718ece9104017104e639ad86e16d3361d8721ddb39ddea94628a8d7a990a63adc17ca63263083397c0f815
data/.copier-answers.yml CHANGED
@@ -3,7 +3,7 @@
3
3
  # See the project for instructions on how to update the project
4
4
  #
5
5
  # Changes here will be overwritten by Copier; NEVER EDIT MANUALLY
6
- _commit: v1.38.0
6
+ _commit: v1.39.0
7
7
  _src_path: https://gitlab.com/gitlab-com/gl-infra/common-template-copier.git
8
8
  ee_licensed: false
9
9
  golang: false
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
@@ -18,6 +18,7 @@ module Labkit
18
18
  class << self
19
19
  def register_wrapper_pattern(pattern)
20
20
  wrapper_patterns << pattern
21
+ @combined_ignore_pattern = nil
21
22
  end
22
23
 
23
24
  def wrapper_patterns
@@ -26,6 +27,11 @@ module Labkit
26
27
 
27
28
  def reset_wrapper_patterns!
28
29
  @wrapper_patterns = nil
30
+ @combined_ignore_pattern = nil
31
+ end
32
+
33
+ def combined_ignore_pattern
34
+ @combined_ignore_pattern ||= Regexp.union(IGNORE_PATHS + wrapper_patterns)
29
35
  end
30
36
  end
31
37
 
@@ -66,13 +72,13 @@ module Labkit
66
72
  def determine_callsite
67
73
  locations = caller_locations(INTERNAL_FRAMES_TO_SKIP, MAX_FRAMES_TO_INSPECT) || []
68
74
  locations = caller_locations(1, MAX_FRAMES_TO_INSPECT) || [] if locations.empty?
75
+ ignore_pattern = LogInterceptor.combined_ignore_pattern
69
76
 
70
77
  locations.find do |loc|
71
78
  path = loc.path
72
79
 
73
80
  next if path == __FILE__
74
- next if IGNORE_PATHS.any? { |pattern| pattern.match?(path) }
75
- next if LogInterceptor.wrapper_patterns.any? { |pattern| pattern.match?(path) }
81
+ next if ignore_pattern.match?(path)
76
82
 
77
83
  true
78
84
  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.3
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