gitlab-labkit 0.42.1 → 0.42.2

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.
Files changed (28) hide show
  1. checksums.yaml +4 -4
  2. data/.gitlab-ci-asdf-versions.yml +1 -1
  3. data/.pre-commit-config.yaml +1 -1
  4. data/.tool-versions +1 -1
  5. data/README.md +1 -1
  6. data/config/{covered_experiences → user_experience_slis}/schema.json +5 -5
  7. data/lib/gitlab-labkit.rb +2 -1
  8. data/lib/labkit/middleware/rack.rb +3 -3
  9. data/lib/labkit/middleware/sidekiq/client.rb +1 -1
  10. data/lib/labkit/middleware/sidekiq/server.rb +1 -1
  11. data/lib/labkit/middleware/sidekiq/{covered_experience → user_experience_sli}/client.rb +4 -4
  12. data/lib/labkit/middleware/sidekiq/{covered_experience → user_experience_sli}/server.rb +4 -4
  13. data/lib/labkit/middleware/sidekiq/user_experience_sli.rb +17 -0
  14. data/lib/labkit/middleware/sidekiq.rb +2 -1
  15. data/lib/labkit/rspec/README.md +36 -27
  16. data/lib/labkit/rspec/matchers/{covered_experience_matchers.rb → user_experience_matchers.rb} +53 -47
  17. data/lib/labkit/rspec/matchers.rb +1 -1
  18. data/lib/labkit/{covered_experience → user_experience_sli}/README.md +28 -28
  19. data/lib/labkit/{covered_experience → user_experience_sli}/current.rb +7 -7
  20. data/lib/labkit/user_experience_sli/error.rb +9 -0
  21. data/lib/labkit/{covered_experience → user_experience_sli}/experience.rb +26 -26
  22. data/lib/labkit/{covered_experience → user_experience_sli}/null.rb +2 -2
  23. data/lib/labkit/{covered_experience → user_experience_sli}/registry.rb +13 -13
  24. data/lib/labkit/{covered_experience.rb → user_experience_sli.rb} +16 -11
  25. metadata +14 -14
  26. data/lib/labkit/covered_experience/error.rb +0 -9
  27. data/lib/labkit/middleware/sidekiq/covered_experience.rb +0 -14
  28. /data/config/{covered_experiences → user_experience_slis}/testing_sample.yml +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 869346480f346d49795eaf4f80e028c4cdbbdb8826345cfcfdff8ddf8e1887fd
4
- data.tar.gz: 63ce86b345417ab4c6ad076dd6f83baca61d4e127c478b857e509c4b34814000
3
+ metadata.gz: cefb3ce3a1f0b663c7d4ac1a60d0b4ed3a6ecb8b170efac046f07e5d700a0b66
4
+ data.tar.gz: 3cb390d7949d332aaa959c03fe1a0d152100067e3822f0832327583972e7ad46
5
5
  SHA512:
6
- metadata.gz: c18e81580f71d9d6833e5d7c07d58fb699ec82df5d8707af38adbedabe6e7a197d0fe1e3cef00f0df7afa740dc5f343c100faf283e97d586419a1134bcf0501b
7
- data.tar.gz: c5d346b9f186a33faa420e5e6fe8513f7af58c829748fe98470c5b6d45d27cb0c2620f56f4cca56729e896ea3daf59d9caa3bdca4aad95b79c3fed5b0052635c
6
+ metadata.gz: 74ac536ebabf46339787079b5c972c8541a4b3d3bd15a597395b110adb1c20fff19ec8bdb554fcf57fc4a36ecbe39c26369bf5c1f4fadfc309bfc5f96c3cb6ee
7
+ data.tar.gz: b3fa11140a2d30d29af280f76887afe57fa0b4c94eb4b73112d1dde67dfcf35a59bb1bb24e32827ea3c30cfddeb3ddcedb438923ca2d6199d72fc0b0182dd6fa
@@ -1,5 +1,5 @@
1
1
  # DO NOT MANUALLY EDIT; Run ./scripts/update-asdf-version-variables.sh to update this
2
2
  variables:
3
- GL_ASDF_RUBY_VERSION: "3.4.6"
3
+ GL_ASDF_RUBY_VERSION: "3.4.7"
4
4
  GL_ASDF_SHELLCHECK_VERSION: "0.11"
5
5
  GL_ASDF_SHFMT_VERSION: "3.12"
@@ -25,7 +25,7 @@ repos:
25
25
  # Documentation available at
26
26
  # https://gitlab.com/gitlab-com/gl-infra/common-ci-tasks/-/blob/main/docs/pre-commit.md
27
27
  - repo: https://gitlab.com/gitlab-com/gl-infra/common-ci-tasks
28
- rev: v2.94 # renovate:managed
28
+ rev: v2.98 # renovate:managed
29
29
 
30
30
  hooks:
31
31
  - id: shellcheck # Run shellcheck for changed Shell files
data/.tool-versions CHANGED
@@ -1,3 +1,3 @@
1
- ruby 3.4.6
1
+ ruby 3.4.7
2
2
  shfmt 3.12
3
3
  shellcheck 0.11
data/README.md CHANGED
@@ -20,7 +20,7 @@ LabKit-Ruby provides functionality in a number of areas:
20
20
 
21
21
  1. `Labkit::Context` used for providing context information to log messages.
22
22
  1. `Labkit::Correlation` for accessing the correlation id. (Generated and propagated by `Labkit::Context`)
23
- 1. `Labkit::CoveredExperience` for tracking covered experiences. More on the [README](./lib/labkit/covered_experience/README.md).
23
+ 1. `Labkit::UserExperienceSli` for tracking User Experience SLIs. More on the [README](./lib/labkit/user_experience_sli/README.md).
24
24
  1. `Labkit::FIPS` for checking for FIPS mode and using FIPS-compliant algorithms.
25
25
  1. `Labkit::Logging` for sanitizing log messages.
26
26
  1. `Labkit::Metrics` for metrics. More on the [README](./lib/labkit/metrics/README.md).
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "$schema": "http://json-schema.org/draft-06/schema#",
3
- "$id": "https://gitlab.com/gitlab-org/ruby/gems/labkit-ruby/-/raw/master/config/covered_experiences/schema.json",
4
- "title": "Covered Experience Definition",
5
- "description": "Schema for GitLab Covered Experience files",
3
+ "$id": "https://gitlab.com/gitlab-org/ruby/gems/labkit-ruby/-/raw/master/config/user_experience_slis/schema.json",
4
+ "title": "User Experience SLI Definition",
5
+ "description": "Schema for GitLab User Experience SLI files",
6
6
  "type": "object",
7
7
  "properties": {
8
8
  "description": {
9
9
  "type": "string",
10
10
  "minLength": 1,
11
- "description": "Human-readable description of the covered experience"
11
+ "description": "Human-readable description of the user experience"
12
12
  },
13
13
  "feature_category": {
14
14
  "type": "string",
@@ -23,7 +23,7 @@
23
23
  "async_fast",
24
24
  "async_slow"
25
25
  ],
26
- "description": "Urgency level for this covered experience"
26
+ "description": "Urgency level for this user experience"
27
27
  }
28
28
  },
29
29
  "required": [
data/lib/gitlab-labkit.rb CHANGED
@@ -9,7 +9,8 @@ module Labkit
9
9
 
10
10
  autoload :Context, "labkit/context"
11
11
  autoload :Correlation, "labkit/correlation"
12
- autoload :CoveredExperience, "labkit/covered_experience"
12
+ autoload :CoveredExperience, "labkit/user_experience_sli" # Backward compatibility alias
13
+ autoload :UserExperienceSli, "labkit/user_experience_sli"
13
14
  autoload :FIPS, "labkit/fips"
14
15
  autoload :Tracing, "labkit/tracing"
15
16
  autoload :Logging, "labkit/logging"
@@ -59,13 +59,13 @@ module Labkit
59
59
  # 4. Microservices or API-only applications with minimal middleware
60
60
  # 5. Background job processors that use Rack but not Rails' full stack
61
61
  #
62
- # By explicitly resetting here, we ensure covered experiences are properly
62
+ # By explicitly resetting here, we ensure user experiences are properly
63
63
  # cleaned up regardless of the application framework or middleware configuration.
64
64
  def reset_current_experiences
65
65
  # Only reset if the Current class is loaded to avoid unnecessary dependencies
66
- return unless defined?(Labkit::CoveredExperience::Current)
66
+ return unless defined?(Labkit::UserExperienceSli::Current)
67
67
 
68
- Labkit::CoveredExperience::Current.reset
68
+ Labkit::UserExperienceSli::Current.reset
69
69
  end
70
70
  end
71
71
  end
@@ -13,7 +13,7 @@ module Labkit
13
13
  @chain ||= ::Sidekiq::Middleware::Chain.new do |chain|
14
14
  chain.add Labkit::Middleware::Sidekiq::Context::Client
15
15
  chain.add Labkit::Middleware::Sidekiq::Tracing::Client if Labkit::Tracing.enabled?
16
- chain.add Labkit::Middleware::Sidekiq::CoveredExperience::Client
16
+ chain.add Labkit::Middleware::Sidekiq::UserExperienceSli::Client
17
17
  end
18
18
  end
19
19
 
@@ -13,7 +13,7 @@ module Labkit
13
13
  @chain ||= ::Sidekiq::Middleware::Chain.new do |chain|
14
14
  chain.add Labkit::Middleware::Sidekiq::Context::Server
15
15
  chain.add Labkit::Middleware::Sidekiq::Tracing::Server if Labkit::Tracing.enabled?
16
- chain.add Labkit::Middleware::Sidekiq::CoveredExperience::Server
16
+ chain.add Labkit::Middleware::Sidekiq::UserExperienceSli::Server
17
17
  end
18
18
  end
19
19
 
@@ -1,22 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'labkit/covered_experience/current'
3
+ require 'labkit/user_experience_sli/current'
4
4
 
5
5
  module Labkit
6
6
  module Middleware
7
7
  module Sidekiq
8
- module CoveredExperience
8
+ module UserExperienceSli
9
9
  # This middleware for Sidekiq-client wraps scheduling jobs with covered
10
10
  # experience context. It retrieves the current experiences and
11
11
  # populates the job with them.
12
12
  class Client
13
13
  def call(worker_class, job, _queue, _redis_pool)
14
- data = Labkit::CoveredExperience::Current.active_experiences.inject({}) do |data, (_, xp)|
14
+ data = Labkit::UserExperienceSli::Current.active_experiences.inject({}) do |data, (_, xp)|
15
15
  xp.checkpoint(checkpoint_action: "sidekiq_job_scheduled", worker: worker_class.to_s)
16
16
  data.merge!(xp.to_h)
17
17
  end
18
18
 
19
- job[Labkit::CoveredExperience::Current::AGGREGATION_KEY] = data unless data.empty?
19
+ job[Labkit::UserExperienceSli::Current::AGGREGATION_KEY] = data unless data.empty?
20
20
 
21
21
  yield
22
22
  end
@@ -3,20 +3,20 @@
3
3
  module Labkit
4
4
  module Middleware
5
5
  module Sidekiq
6
- module CoveredExperience
6
+ module UserExperienceSli
7
7
  # This middleware for Sidekiq-server rehydrates the current experiences
8
8
  # serialized to the job
9
9
  class Server
10
10
  def call(_worker_class, job, _queue)
11
- job[Labkit::CoveredExperience::Current::AGGREGATION_KEY]&.each do |experience_id, data|
12
- xp = Labkit::CoveredExperience::Current.rehydrate(experience_id, **data)
11
+ job[Labkit::UserExperienceSli::Current::AGGREGATION_KEY]&.each do |experience_id, data|
12
+ xp = Labkit::UserExperienceSli::Current.rehydrate(experience_id, **data)
13
13
  xp.checkpoint(checkpoint_action: "sidekiq_job_started", worker: job["class"].to_s)
14
14
  end
15
15
 
16
16
  yield
17
17
 
18
18
  ensure
19
- Labkit::CoveredExperience::Current.reset
19
+ Labkit::UserExperienceSli::Current.reset
20
20
  end
21
21
  end
22
22
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Labkit
4
+ module Middleware
5
+ module Sidekiq
6
+ # This module contains all the sidekiq middleware regarding user
7
+ # experience SLIs
8
+ module UserExperienceSli
9
+ autoload :Client, "labkit/middleware/sidekiq/user_experience_sli/client"
10
+ autoload :Server, "labkit/middleware/sidekiq/user_experience_sli/server"
11
+ end
12
+
13
+ # Backward compatibility alias
14
+ CoveredExperience = UserExperienceSli
15
+ end
16
+ end
17
+ end
@@ -7,7 +7,8 @@ module Labkit
7
7
  autoload :Client, "labkit/middleware/sidekiq/client"
8
8
  autoload :Server, "labkit/middleware/sidekiq/server"
9
9
  autoload :Context, "labkit/middleware/sidekiq/context"
10
- autoload :CoveredExperience, "labkit/middleware/sidekiq/covered_experience"
10
+ autoload :UserExperienceSli, "labkit/middleware/sidekiq/user_experience_sli"
11
+ autoload :CoveredExperience, "labkit/middleware/sidekiq/user_experience_sli" # Backward compatibility
11
12
  autoload :Tracing, "labkit/middleware/sidekiq/tracing"
12
13
  end
13
14
  end
@@ -19,61 +19,70 @@ This approach ensures that:
19
19
 
20
20
  ## Available Matchers
21
21
 
22
- ### Covered Experience Matchers
22
+ ### User Experience Matchers
23
23
 
24
- These matchers help you test that your code properly instruments covered experiences with the expected metrics.
24
+ These matchers help you test that your code properly instruments user experience SLIs with the expected metrics.
25
25
 
26
- #### `start_covered_experience`
26
+ #### `start_user_experience`
27
27
 
28
- Tests that a covered experience is started (checkpoint=start metric is incremented).
28
+ Tests that a user experience is started (checkpoint=start metric is incremented).
29
29
 
30
30
  ```ruby
31
- expect { subject }.to start_covered_experience('rails_request')
31
+ expect { subject }.to start_user_experience('rails_request')
32
32
 
33
33
  # Test that it does NOT start
34
- expect { subject }.not_to start_covered_experience('rails_request')
34
+ expect { subject }.not_to start_user_experience('rails_request')
35
35
  ```
36
36
 
37
- #### `checkpoint_covered_experience`
37
+ #### `checkpoint_user_experience`
38
38
 
39
- Tests that a covered experience checkpoint is recorded (checkpoint=intermediate metric is incremented).
39
+ Tests that a user experience checkpoint is recorded (checkpoint=intermediate metric is incremented).
40
40
 
41
41
  ```ruby
42
- expect { subject }.to checkpoint_covered_experience('rails_request')
42
+ expect { subject }.to checkpoint_user_experience('rails_request')
43
43
 
44
44
  # Test that it does NOT checkpoint
45
- expect { subject }.not_to checkpoint_covered_experience('rails_request')
45
+ expect { subject }.not_to checkpoint_user_experience('rails_request')
46
46
  ```
47
47
 
48
- #### `resume_covered_experience`
48
+ #### `resume_user_experience`
49
49
 
50
- Tests that a covered experience is resumed (checkpoint=intermediate metric is incremented). This is an alias for `checkpoint_covered_experience` that provides more semantic meaning when testing code that resumes a covered experience previously started.
50
+ Tests that a user experience is resumed (checkpoint=intermediate metric is incremented). This is an alias for `checkpoint_user_experience` that provides more semantic meaning when testing code that resumes a user experience previously started.
51
51
 
52
52
  ```ruby
53
- expect { subject }.to resume_covered_experience('rails_request')
53
+ expect { subject }.to resume_user_experience('rails_request')
54
54
 
55
55
  # Test that it does NOT resume
56
- expect { subject }.not_to resume_covered_experience('rails_request')
56
+ expect { subject }.not_to resume_user_experience('rails_request')
57
57
  ```
58
58
 
59
- #### `complete_covered_experience`
59
+ #### `complete_user_experience`
60
60
 
61
- Tests that a covered experience is completed with the expected metrics:
62
- - `gitlab_covered_experience_checkpoint_total` (with checkpoint=end)
63
- - `gitlab_covered_experience_total` (with error flag)
64
- - `gitlab_covered_experience_apdex_total` (with success flag)
61
+ Tests that a user experience is completed with the expected metrics:
62
+ - `gitlab_user_experience_checkpoint_total` (with checkpoint=end)
63
+ - `gitlab_user_experience_total` (with error flag)
64
+ - `gitlab_user_experience_apdex_total` (with success flag)
65
65
 
66
66
  ```ruby
67
67
  # Test successful completion
68
- expect { subject }.to complete_covered_experience('rails_request')
68
+ expect { subject }.to complete_user_experience('rails_request')
69
69
 
70
70
  # Test completion with error
71
- expect { subject }.to complete_covered_experience('rails_request', error: true, success: false)
71
+ expect { subject }.to complete_user_experience('rails_request', error: true, success: false)
72
72
 
73
73
  # Test that it does NOT complete
74
- expect { subject }.not_to complete_covered_experience('rails_request')
74
+ expect { subject }.not_to complete_user_experience('rails_request')
75
75
  ```
76
76
 
77
+ ### Legacy Matchers (Backward Compatibility)
78
+
79
+ For backward compatibility, the following legacy matchers are still available but deprecated. Please migrate to the new `*_user_experience` matchers above.
80
+
81
+ - `start_covered_experience`
82
+ - `checkpoint_covered_experience`
83
+ - `resume_covered_experience`
84
+ - `complete_covered_experience`
85
+
77
86
  ## Example Usage
78
87
 
79
88
  ### In your spec_helper.rb or rails_helper.rb:
@@ -96,8 +105,8 @@ end
96
105
  RSpec.describe MyController, type: :controller do
97
106
  describe '#index' do
98
107
  it 'instruments the request properly' do
99
- expect { get :index }.to start_covered_experience('rails_request')
100
- .and complete_covered_experience('rails_request')
108
+ expect { get :index }.to start_user_experience('rails_request')
109
+ .and complete_user_experience('rails_request')
101
110
  end
102
111
 
103
112
  context 'when an error occurs' do
@@ -106,7 +115,7 @@ RSpec.describe MyController, type: :controller do
106
115
  end
107
116
 
108
117
  it 'records the error in metrics' do
109
- expect { get :index }.to complete_covered_experience('rails_request', error: true, success: false)
118
+ expect { get :index }.to complete_user_experience('rails_request', error: true, success: false)
110
119
  end
111
120
  end
112
121
  end
@@ -127,6 +136,6 @@ end
127
136
 
128
137
  ## Requirements
129
138
 
130
- - The covered experience must be registered in `Labkit::CoveredExperience::Registry`
139
+ - The user experience SLI must be registered in `Labkit::UserExperienceSli::Registry`
131
140
  - Metrics must be properly configured in your test environment
132
- - The code under test must use Labkit's covered experience instrumentation
141
+ - The code under test must use Labkit's user experience SLI instrumentation
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # RSpec matchers for testing Labkit CoveredExperience functionality
3
+ # RSpec matchers for testing Labkit UserExperience functionality
4
4
  #
5
5
  # This file must be explicitly required in your test setup:
6
6
  # require 'labkit/rspec/matchers'
@@ -10,49 +10,49 @@ raise LoadError, "RSpec is not loaded. Please require 'rspec' before requiring '
10
10
  module Labkit
11
11
  module RSpec
12
12
  module Matchers
13
- # Helper module for CoveredExperience functionality
14
- module CoveredExperience
15
- def attributes(covered_experience_id)
16
- raise ArgumentError, "covered_experience_id is required" if covered_experience_id.nil?
13
+ # Helper module for UserExperience functionality
14
+ module UserExperience
15
+ def attributes(user_experience_id)
16
+ raise ArgumentError, "user_experience_id is required" if user_experience_id.nil?
17
17
 
18
- definition = Labkit::CoveredExperience::Registry.new[covered_experience_id]
19
- definition.to_h.slice(:covered_experience, :feature_category, :urgency)
18
+ definition = Labkit::UserExperienceSli::Registry.new[user_experience_id]
19
+ definition.to_h.slice(:user_experience_id, :feature_category, :urgency)
20
20
  end
21
21
 
22
22
  def checkpoint_counter
23
- Labkit::Metrics::Client.get(:gitlab_covered_experience_checkpoint_total)
23
+ Labkit::Metrics::Client.get(:gitlab_user_experience_checkpoint_total)
24
24
  end
25
25
 
26
26
  def total_counter
27
- Labkit::Metrics::Client.get(:gitlab_covered_experience_total)
27
+ Labkit::Metrics::Client.get(:gitlab_user_experience_total)
28
28
  end
29
29
 
30
30
  def apdex_counter
31
- Labkit::Metrics::Client.get(:gitlab_covered_experience_apdex_total)
31
+ Labkit::Metrics::Client.get(:gitlab_user_experience_apdex_total)
32
32
  end
33
33
  end
34
34
  end
35
35
  end
36
36
  end
37
37
 
38
- # Matcher for verifying CoveredExperience start metrics instrumentation.
38
+ # Matcher for verifying UserExperience start metrics instrumentation.
39
39
  #
40
40
  # Usage:
41
- # expect { subject }.to start_covered_experience('rails_request')
41
+ # expect { subject }.to start_user_experience('rails_request')
42
42
  #
43
43
  # This matcher verifies that the following metric is incremented:
44
- # - gitlab_covered_experience_checkpoint_total (with checkpoint=start)
44
+ # - gitlab_user_experience_checkpoint_total (with checkpoint=start)
45
45
  #
46
46
  # Parameters:
47
- # - covered_experience_id: Required. The ID of the covered experience (e.g., 'rails_request')
48
- RSpec::Matchers.define :start_covered_experience do |covered_experience_id|
49
- include Labkit::RSpec::Matchers::CoveredExperience
47
+ # - user_experience_id: Required. The ID of the user experience (e.g., 'rails_request')
48
+ RSpec::Matchers.define :start_user_experience do |user_experience_id|
49
+ include Labkit::RSpec::Matchers::UserExperience
50
50
 
51
- description { "start covered experience '#{covered_experience_id}'" }
51
+ description { "start user experience '#{user_experience_id}'" }
52
52
  supports_block_expectations
53
53
 
54
54
  match do |actual|
55
- labels = attributes(covered_experience_id)
55
+ labels = attributes(user_experience_id)
56
56
 
57
57
  checkpoint_before = checkpoint_counter&.get(labels.merge(checkpoint: "start")).to_i
58
58
 
@@ -66,29 +66,29 @@ RSpec::Matchers.define :start_covered_experience do |covered_experience_id|
66
66
  end
67
67
 
68
68
  failure_message do
69
- "Failed to checkpoint covered experience '#{covered_experience_id}':\n" \
69
+ "Failed to checkpoint user experience '#{user_experience_id}':\n" \
70
70
  "expected checkpoint='start' counter to increase by 1, but increased by #{@checkpoint_change}"
71
71
  end
72
72
  end
73
73
 
74
- # Matcher for verifying CoveredExperience checkpoint metrics instrumentation.
74
+ # Matcher for verifying UserExperience checkpoint metrics instrumentation.
75
75
  #
76
76
  # Usage:
77
- # expect { subject }.to checkpoint_covered_experience('rails_request')
77
+ # expect { subject }.to checkpoint_user_experience('rails_request')
78
78
  #
79
79
  # This matcher verifies that the following metric is incremented:
80
- # - gitlab_covered_experience_checkpoint_total (with checkpoint=intermediate)
80
+ # - gitlab_user_experience_checkpoint_total (with checkpoint=intermediate)
81
81
  #
82
82
  # Parameters:
83
- # - covered_experience_id: Required. The ID of the covered experience (e.g., 'rails_request')
84
- RSpec::Matchers.define :checkpoint_covered_experience do |covered_experience_id, by: 1|
85
- include Labkit::RSpec::Matchers::CoveredExperience
83
+ # - user_experience_id: Required. The ID of the user experience (e.g., 'rails_request')
84
+ RSpec::Matchers.define :checkpoint_user_experience do |user_experience_id, by: 1|
85
+ include Labkit::RSpec::Matchers::UserExperience
86
86
 
87
- description { "checkpoint covered experience '#{covered_experience_id}'" }
87
+ description { "checkpoint user experience '#{user_experience_id}'" }
88
88
  supports_block_expectations
89
89
 
90
90
  match do |actual|
91
- labels = attributes(covered_experience_id)
91
+ labels = attributes(user_experience_id)
92
92
 
93
93
  checkpoint_before = checkpoint_counter&.get(labels.merge(checkpoint: "intermediate")).to_i
94
94
 
@@ -104,12 +104,12 @@ RSpec::Matchers.define :checkpoint_covered_experience do |covered_experience_id,
104
104
  end
105
105
 
106
106
  failure_message do
107
- "Failed to checkpoint covered experience '#{covered_experience_id}':\n" \
107
+ "Failed to checkpoint user experience '#{user_experience_id}':\n" \
108
108
  "expected checkpoint='intermediate' counter to increase by at least #{by}, but increased by #{@checkpoint_change}"
109
109
  end
110
110
 
111
111
  match_when_negated do |actual|
112
- labels = attributes(covered_experience_id)
112
+ labels = attributes(user_experience_id)
113
113
 
114
114
  checkpoint_before = checkpoint_counter&.get(labels.merge(checkpoint: "intermediate")).to_i
115
115
 
@@ -122,36 +122,36 @@ RSpec::Matchers.define :checkpoint_covered_experience do |covered_experience_id,
122
122
  end
123
123
 
124
124
  failure_message_when_negated do
125
- "Expected covered experience '#{covered_experience_id}' NOT to checkpoint:\n" \
125
+ "Expected user experience '#{user_experience_id}' NOT to checkpoint:\n" \
126
126
  "expected checkpoint='intermediate' counter not to increase, but increased by #{@checkpoint_change}"
127
127
  end
128
128
  end
129
129
 
130
- # Alias for checkpoint_covered_experience matcher
131
- RSpec::Matchers.alias_matcher :resume_covered_experience, :checkpoint_covered_experience
130
+ # Alias for checkpoint_user_experience matcher
131
+ RSpec::Matchers.alias_matcher :resume_user_experience, :checkpoint_user_experience
132
132
 
133
- # Matcher for verifying CoveredExperience completion metrics instrumentation.
133
+ # Matcher for verifying UserExperience completion metrics instrumentation.
134
134
  #
135
135
  # Usage:
136
- # expect { subject }.to complete_covered_experience('rails_request')
136
+ # expect { subject }.to complete_user_experience('rails_request')
137
137
  #
138
138
  # This matcher verifies that the following metrics are incremented with specific labels:
139
- # - gitlab_covered_experience_checkpoint_total (with checkpoint=end)
140
- # - gitlab_covered_experience_total (with error=false)
141
- # - gitlab_covered_experience_apdex_total (with success=true)
139
+ # - gitlab_user_experience_checkpoint_total (with checkpoint=end)
140
+ # - gitlab_user_experience_total (with error=false)
141
+ # - gitlab_user_experience_apdex_total (with success=true)
142
142
  #
143
143
  # Parameters:
144
- # - covered_experience_id: Required. The ID of the covered experience (e.g., 'rails_request')
145
- # - error: Optional. The expected error flag for gitlab_covered_experience_total (false by default)
146
- # - success: Optional. The expected success flag for gitlab_covered_experience_apdex_total (true by default)
147
- RSpec::Matchers.define :complete_covered_experience do |covered_experience_id, error: false, success: true|
148
- include Labkit::RSpec::Matchers::CoveredExperience
144
+ # - user_experience_id: Required. The ID of the user experience (e.g., 'rails_request')
145
+ # - error: Optional. The expected error flag for gitlab_user_experience_total (false by default)
146
+ # - success: Optional. The expected success flag for gitlab_user_experience_apdex_total (true by default)
147
+ RSpec::Matchers.define :complete_user_experience do |user_experience_id, error: false, success: true|
148
+ include Labkit::RSpec::Matchers::UserExperience
149
149
 
150
- description { "complete covered experience '#{covered_experience_id}'" }
150
+ description { "complete user experience '#{user_experience_id}'" }
151
151
  supports_block_expectations
152
152
 
153
153
  match do |actual|
154
- labels = attributes(covered_experience_id)
154
+ labels = attributes(user_experience_id)
155
155
 
156
156
  checkpoint_before = checkpoint_counter&.get(labels.merge(checkpoint: "end")).to_i
157
157
  total_before = total_counter&.get(labels.merge(error: error)).to_i
@@ -170,14 +170,14 @@ RSpec::Matchers.define :complete_covered_experience do |covered_experience_id, e
170
170
  end
171
171
 
172
172
  failure_message do
173
- "Failed to complete covered experience '#{covered_experience_id}':\n" \
173
+ "Failed to complete user experience '#{user_experience_id}':\n" \
174
174
  "expected checkpoint='end' counter to increase by 1, but increased by #{@checkpoint_change}\n" \
175
175
  "expected total='error: #{error}' counter to increase by 1, but increased by #{@total_change}\n" \
176
176
  "expected apdex='success: #{success}' counter to increase by 1, but increased by #{@apdex_change}"
177
177
  end
178
178
 
179
179
  match_when_negated do |actual|
180
- labels = attributes(covered_experience_id)
180
+ labels = attributes(user_experience_id)
181
181
 
182
182
  checkpoint_before = checkpoint_counter&.get(labels.merge(checkpoint: "end")).to_i
183
183
  total_before = total_counter&.get(labels.merge(error: error)).to_i
@@ -196,9 +196,15 @@ RSpec::Matchers.define :complete_covered_experience do |covered_experience_id, e
196
196
  end
197
197
 
198
198
  failure_message_when_negated do
199
- "Failed covered experience '#{covered_experience_id}' NOT to complete:\n" \
199
+ "Failed user experience '#{user_experience_id}' NOT to complete:\n" \
200
200
  "expected checkpoint='end' counter to increase by 0, but increased by #{@checkpoint_change}\n" \
201
201
  "expected total='error: #{error}' counter to increase by 0, but increased by #{@total_change}\n" \
202
202
  "expected apdex='success: #{success}' counter to increase by 0, but increased by #{@apdex_change}"
203
203
  end
204
204
  end
205
+
206
+ # Backward compatibility matchers for CoveredExperience
207
+ RSpec::Matchers.alias_matcher :start_covered_experience, :start_user_experience
208
+ RSpec::Matchers.alias_matcher :checkpoint_covered_experience, :checkpoint_user_experience
209
+ RSpec::Matchers.alias_matcher :resume_covered_experience, :checkpoint_user_experience
210
+ RSpec::Matchers.alias_matcher :complete_covered_experience, :complete_user_experience
@@ -7,4 +7,4 @@
7
7
 
8
8
  raise LoadError, "RSpec is not loaded. Please require 'rspec' before requiring 'labkit/rspec/matchers'" unless defined?(RSpec)
9
9
 
10
- require_relative 'matchers/covered_experience_matchers'
10
+ require_relative 'matchers/user_experience_matchers'
@@ -1,51 +1,51 @@
1
- # Covered Experience
1
+ # User Experience SLIs
2
2
 
3
- This module covers the definition for Covered Experiences, as described in the [blueprint](https://handbook.gitlab.com/handbook/engineering/architecture/design-documents/covered_experience_slis/#covered-experience-definition).
3
+ This module covers the definition for User Experience SLIs, as described in the [blueprint](https://handbook.gitlab.com/handbook/engineering/architecture/design-documents/user_experience_slis/#user-experience-sli-definition).
4
4
 
5
5
  ## Configuration
6
6
 
7
7
  ### Logger Configuration
8
8
 
9
- By default, `Labkit::CoveredExperience` uses `Labkit::Logging::JsonLogger.new($stdout)` for logging. You can configure a custom logger:
9
+ By default, `Labkit::UserExperienceSli` uses `Labkit::Logging::JsonLogger.new($stdout)` for logging. You can configure a custom logger:
10
10
 
11
11
  ```ruby
12
- Labkit::CoveredExperience.configure do |config|
12
+ Labkit::UserExperienceSli.configure do |config|
13
13
  config.logger = Labkit::Logging::JsonLogger.new($stdout)
14
14
  end
15
15
  ```
16
16
 
17
- This configuration affects all Covered Experience instances and their logging output.
17
+ This configuration affects all User Experience SLI instances and their logging output.
18
18
 
19
19
  ### Registry Path Configuration
20
20
 
21
- By default, covered experience definitions are loaded from the `config/covered_experiences` directory. You can configure a custom registry path:
21
+ By default, user experience SLI definitions are loaded from the `config/user_experience_slis` directory. You can configure a custom registry path:
22
22
 
23
23
  ```ruby
24
- Labkit::CoveredExperience.configure do |config|
24
+ Labkit::UserExperienceSli.configure do |config|
25
25
  config.registry_path = "my/custom/path"
26
26
  end
27
27
  ```
28
28
 
29
29
  This allows you to:
30
- - Store covered experience definitions in a different directory structure
30
+ - Store user experience SLI definitions in a different directory structure
31
31
  - Use different paths for different environments
32
32
  - Organize definitions according to your application's needs
33
33
 
34
34
  **Note:** The registry is automatically reset when the configuration changes, so the new path takes effect immediately.
35
35
 
36
- ### Covered Experience Definitions
36
+ ### User Experience Definitions
37
37
 
38
- Covered experience definitions will be lazy loaded from the default directory (`config/covered_experiences`).
38
+ User Experience SLI definitions will be lazy loaded from the default directory (`config/user_experience_slis`).
39
39
 
40
- Create a new covered experience file in the registry directory, e.g. config/covered_experiences/merge_request_creation.yaml
40
+ Create a new user experience SLI file in the registry directory, e.g. config/user_experience_slis/merge_request_creation.yaml
41
41
 
42
- The basename of the file will be taken as the covered_experience_id.
42
+ The basename of the file will be taken as the user_experience_id.
43
43
 
44
44
  The schema header is optional, but if you're using VSCode (or any other editor with support), you can get them validated
45
45
  instantaneously in the editor via a [JSON schema plugin](https://marketplace.visualstudio.com/items?itemName=remcohaszing.schemastore).
46
46
 
47
47
  ```yaml
48
- # yaml-language-server: $schema=https://gitlab.com/gitlab-org/ruby/gems/labkit-ruby/-/raw/master/config/covered_experiences/schema.json
48
+ # yaml-language-server: $schema=https://gitlab.com/gitlab-org/ruby/gems/labkit-ruby/-/raw/master/config/user_experience_slis/schema.json
49
49
  description: "Creating a new merge request in a project"
50
50
  feature_category: "source_code_management"
51
51
  urgency: "sync_fast"
@@ -66,22 +66,22 @@ https://docs.gitlab.com/development/feature_categorization/#feature-categorizati
66
66
 
67
67
  ## Usage
68
68
 
69
- The `Labkit::CoveredExperience` module provides a simple API for measuring and tracking covered experiences in your application.
69
+ The `Labkit::UserExperienceSli` module provides a simple API for measuring and tracking user experience SLIs in your application.
70
70
 
71
71
 
72
- #### Accessing a Covered Experience
72
+ #### Accessing a User Experience SLI
73
73
 
74
74
  ```ruby
75
- # Get a covered experience by ID
76
- experience = Labkit::CoveredExperience.get('merge_request_creation')
75
+ # Get a user experience SLI by ID
76
+ experience = Labkit::UserExperienceSli.get('merge_request_creation')
77
77
  ```
78
78
 
79
79
  #### Using with a Block (Recommended)
80
80
 
81
- The simplest way to use covered experiences is with a block, which automatically handles starting and completing the experience:
81
+ The simplest way to use user experience SLIs is with a block, which automatically handles starting and completing the experience:
82
82
 
83
83
  ```ruby
84
- Labkit::CoveredExperience.start('merge_request_creation') do |experience|
84
+ Labkit::UserExperienceSli.start('merge_request_creation') do |experience|
85
85
  # Your code here
86
86
  create_merge_request
87
87
 
@@ -100,7 +100,7 @@ end
100
100
  For more control, you can manually start, checkpoint, and complete experiences:
101
101
 
102
102
  ```ruby
103
- experience = Labkit::CoveredExperience.get('merge_request_creation')
103
+ experience = Labkit::UserExperienceSli.get('merge_request_creation')
104
104
  experience.start
105
105
 
106
106
  # Perform some work
@@ -119,13 +119,13 @@ experience.complete
119
119
 
120
120
  #### Resuming Experiences
121
121
 
122
- You can resume a covered experience that was previously started and stored in the context. This is useful for distributed operations or when work spans multiple processes.
122
+ You can resume a user experience SLI that was previously started and stored in the context. This is useful for distributed operations or when work spans multiple processes.
123
123
 
124
- Just like the start method, we can use a block to automatically complete a covered experience:
124
+ Just like the start method, we can use a block to automatically complete a user experience SLI:
125
125
 
126
126
  ```ruby
127
127
  # Resume an experience from context (with block)
128
- Labkit::CoveredExperience.resume(:merge_request_creation) do |experience|
128
+ Labkit::UserExperienceSli.resume(:merge_request_creation) do |experience|
129
129
  # Continue the work from where it left off
130
130
  finalize_merge_request
131
131
 
@@ -139,7 +139,7 @@ Or manually:
139
139
 
140
140
  ```ruby
141
141
  # Resume an experience from context (manual control)
142
- experience = Labkit::CoveredExperience.resume(:merge_request_creation)
142
+ experience = Labkit::UserExperienceSli.resume(:merge_request_creation)
143
143
 
144
144
  # Continue the work
145
145
  finalize_merge_request
@@ -149,14 +149,14 @@ experience.checkpoint
149
149
  experience.complete
150
150
  ```
151
151
 
152
- **Note:** The `resume` method loads the start time from the Labkit context. If no covered experience data exists in the context, it behaves the same as calling methods on an unstarted experience and safely ignores the operation.
152
+ **Note:** The `resume` method loads the start time from the Labkit context. If no user experience SLI data exists in the context, it behaves the same as calling methods on an unstarted experience and safely ignores the operation.
153
153
 
154
154
  ### Error Handling
155
155
 
156
156
  When using the block form, errors are automatically captured:
157
157
 
158
158
  ```ruby
159
- Labkit::CoveredExperience.start('merge_request_creation') do |experience|
159
+ Labkit::UserExperienceSli.start('merge_request_creation') do |experience|
160
160
  # If this raises an exception, it will be captured automatically
161
161
  risky_operation
162
162
  end
@@ -165,7 +165,7 @@ end
165
165
  For manual control, you can mark errors explicitly:
166
166
 
167
167
  ```ruby
168
- experience = Labkit::CoveredExperience.get('merge_request_creation')
168
+ experience = Labkit::UserExperienceSli.get('merge_request_creation')
169
169
  experience.start
170
170
 
171
171
  begin
@@ -180,6 +180,6 @@ end
180
180
 
181
181
  ### Error Behavior
182
182
 
183
- - In `development` and `test` environments, accessing a non-existent covered experience will raise a `NotFoundError`
183
+ - In `development` and `test` environments, accessing a non-existent user experience SLI will raise a `NotFoundError`
184
184
  - In other environments, a null object is returned that safely ignores all method calls
185
185
  - Attempting to checkpoint or complete an unstarted experience will safely ignore the operation
@@ -1,22 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "active_support"
4
- require "labkit/covered_experience/experience"
4
+ require "labkit/user_experience_sli/experience"
5
5
 
6
6
  module Labkit
7
- module CoveredExperience
7
+ module UserExperienceSli
8
8
  # The `Current` class represents a container for the current set
9
- # of `Labkit::CoveredExperience::Experience` instances started and
9
+ # of `Labkit::UserExperienceSli::Experience` instances started and
10
10
  # not yet completed.
11
11
  #
12
12
  # It uses `ActiveSupport::CurrentAttributes` to provide a thread-safe way to
13
13
  # store and access experiences throughout the request and background job lifecycle.
14
14
  #
15
15
  # Example usage:
16
- # Labkit::CoveredExperience::Current.active_experiences << my_experience
17
- # Labkit::CoveredExperience::Current.rehydrate("create_merge_request", "start_time" => "2025-08-22T10:02:15.237Z")
16
+ # Labkit::UserExperienceSli::Current.active_experiences << my_experience
17
+ # Labkit::UserExperienceSli::Current.rehydrate("create_merge_request", "start_time" => "2025-08-22T10:02:15.237Z")
18
18
  class Current < ActiveSupport::CurrentAttributes
19
- AGGREGATION_KEY = 'labkit_covered_experiences'
19
+ AGGREGATION_KEY = 'labkit_user_experiences'
20
20
 
21
21
  attribute :_active_experiences
22
22
 
@@ -25,7 +25,7 @@ module Labkit
25
25
  end
26
26
 
27
27
  def rehydrate(experience_id, **data)
28
- instance = Labkit::CoveredExperience.get(experience_id).rehydrate(data)
28
+ instance = Labkit::UserExperienceSli.get(experience_id).rehydrate(data)
29
29
  active_experiences[instance.id] = instance
30
30
  instance
31
31
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Labkit
4
+ module UserExperienceSli
5
+ UserExperienceError = Class.new(StandardError)
6
+ NotFoundError = Class.new(UserExperienceError)
7
+ ReservedKeywordError = Class.new(UserExperienceError)
8
+ end
9
+ end
@@ -3,11 +3,11 @@
3
3
  require 'active_support/hash_with_indifferent_access'
4
4
  require 'forwardable'
5
5
  require 'labkit/context'
6
- require 'labkit/covered_experience/current'
7
- require 'labkit/covered_experience/error'
6
+ require 'labkit/user_experience_sli/current'
7
+ require 'labkit/user_experience_sli/error'
8
8
 
9
9
  module Labkit
10
- module CoveredExperience
10
+ module UserExperienceSli
11
11
  URGENCY_THRESHOLDS_IN_SECONDS = {
12
12
  sync_fast: 2,
13
13
  sync_slow: 5,
@@ -17,7 +17,7 @@ module Labkit
17
17
 
18
18
  RESERVED_KEYWORDS = %w[
19
19
  checkpoint
20
- covered_experience
20
+ user_experience_id
21
21
  feature_category
22
22
  urgency
23
23
  start_time
@@ -30,7 +30,7 @@ module Labkit
30
30
  success
31
31
  ].freeze
32
32
 
33
- # The `Experience` class represents a single Covered Experience
33
+ # The `Experience` class represents a single User Experience
34
34
  # event to be measured and reported.
35
35
  class Experience
36
36
  extend Forwardable
@@ -42,7 +42,7 @@ module Labkit
42
42
  end
43
43
 
44
44
  def id
45
- @definition.covered_experience
45
+ @definition.user_experience_id
46
46
  end
47
47
 
48
48
  # Rehydrate an Experience instance from serialized data.
@@ -57,21 +57,21 @@ module Labkit
57
57
  self
58
58
  end
59
59
 
60
- # Start the Covered Experience.
60
+ # Start the User Experience.
61
61
  #
62
62
  # @yield [self] When a block is provided, the experience will be completed automatically.
63
63
  # @param extra [Hash] Additional data to include in the log event
64
64
  # @return [self]
65
- # @raise [CoveredExperienceError] If the block raises an error.
65
+ # @raise [UserExperienceError] If the block raises an error.
66
66
  #
67
67
  # Usage:
68
68
  #
69
- # CoveredExperience.new(definition).start do |experience|
69
+ # UserExperience.new(definition).start do |experience|
70
70
  # experience.checkpoint
71
71
  # experience.checkpoint
72
72
  # end
73
73
  #
74
- # experience = CoveredExperience.new(definition)
74
+ # experience = UserExperience.new(definition)
75
75
  # experience.start
76
76
  # experience.checkpoint
77
77
  # experience.complete
@@ -80,14 +80,14 @@ module Labkit
80
80
  checkpoint_counter.increment(checkpoint: "start", **base_labels)
81
81
  log_event("start", **extra)
82
82
 
83
- Labkit::CoveredExperience::Current.active_experiences[id] = self
83
+ Labkit::UserExperienceSli::Current.active_experiences[id] = self
84
84
 
85
85
  return self unless block_given?
86
86
 
87
87
  completable(**extra, &)
88
88
  end
89
89
 
90
- # Checkpoint the Covered Experience.
90
+ # Checkpoint the User Experience.
91
91
  #
92
92
  # @param extra [Hash] Additional data to include in the log event
93
93
  # @return [self]
@@ -101,7 +101,7 @@ module Labkit
101
101
  self
102
102
  end
103
103
 
104
- # Resume the Covered Experience.
104
+ # Resume the User Experience.
105
105
  #
106
106
  # @yield [self] When a block is provided, the experience will be completed automatically.
107
107
  # @param extra [Hash] Additional data to include in the log
@@ -115,7 +115,7 @@ module Labkit
115
115
  completable(**extra, &)
116
116
  end
117
117
 
118
- # Complete the Covered Experience.
118
+ # Complete the User Experience.
119
119
  #
120
120
  # @param extra [Hash] Additional data to include in the log event
121
121
  # @return [self]
@@ -129,7 +129,7 @@ module Labkit
129
129
  total_counter.increment(error: has_error?, **base_labels)
130
130
  apdex_counter.increment(success: apdex_success?, **base_labels) unless has_error?
131
131
  log_event("end", **extra)
132
- Labkit::CoveredExperience::Current.active_experiences.delete(id)
132
+ Labkit::UserExperienceSli::Current.active_experiences.delete(id)
133
133
  end
134
134
 
135
135
  self
@@ -157,13 +157,13 @@ module Labkit
157
157
  private
158
158
 
159
159
  def base_labels
160
- @base_labels ||= @definition.to_h.slice(:covered_experience, :feature_category, :urgency)
160
+ @base_labels ||= @definition.to_h.slice(:user_experience_id, :feature_category, :urgency)
161
161
  end
162
162
 
163
163
  def ensure_started!
164
164
  return @start_time unless @start_time.nil?
165
165
 
166
- warn("Covered Experience #{@definition.covered_experience} not started")
166
+ warn("User Experience #{@definition.user_experience_id} not started")
167
167
  false
168
168
  end
169
169
 
@@ -183,7 +183,7 @@ module Labkit
183
183
  def ensure_incomplete!
184
184
  return true if @end_time.nil?
185
185
 
186
- warn("Covered Experience #{@definition.covered_experience} already completed")
186
+ warn("User Experience #{@definition.user_experience_id} already completed")
187
187
  false
188
188
  end
189
189
 
@@ -204,22 +204,22 @@ module Labkit
204
204
 
205
205
  def checkpoint_counter
206
206
  @checkpoint_counter ||= Labkit::Metrics::Client.counter(
207
- :gitlab_covered_experience_checkpoint_total,
208
- 'Total checkpoints for covered experiences'
207
+ :gitlab_user_experience_checkpoint_total,
208
+ 'Total checkpoints for user experiences'
209
209
  )
210
210
  end
211
211
 
212
212
  def total_counter
213
213
  @total_counter ||= Labkit::Metrics::Client.counter(
214
- :gitlab_covered_experience_total,
215
- 'Total covered experience events (success/failure)'
214
+ :gitlab_user_experience_total,
215
+ 'Total user experience events (success/failure)'
216
216
  )
217
217
  end
218
218
 
219
219
  def apdex_counter
220
220
  @apdex_counter ||= Labkit::Metrics::Client.counter(
221
- :gitlab_covered_experience_apdex_total,
222
- 'Total covered experience apdex events'
221
+ :gitlab_user_experience_apdex_total,
222
+ 'Total user experience apdex events'
223
223
  )
224
224
  end
225
225
 
@@ -233,7 +233,7 @@ module Labkit
233
233
  def build_log_data(event_type, **extra)
234
234
  log_data = ActiveSupport::HashWithIndifferentAccess.new(
235
235
  checkpoint: event_type,
236
- covered_experience: id,
236
+ user_experience_id: id,
237
237
  feature_category: @definition.feature_category,
238
238
  urgency: @definition.urgency,
239
239
  start_time: @start_time,
@@ -275,7 +275,7 @@ module Labkit
275
275
  end
276
276
 
277
277
  def logger
278
- Labkit::CoveredExperience.configuration.logger
278
+ Labkit::UserExperienceSli.configuration.logger
279
279
  end
280
280
  end
281
281
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Labkit
4
- module CoveredExperience
5
- # Fakes Labkit::CoveredExperience::Experience.
4
+ module UserExperienceSli
5
+ # Fakes Labkit::UserExperienceSli::Experience.
6
6
  class Null
7
7
  include Singleton
8
8
 
@@ -6,29 +6,29 @@ require 'pathname'
6
6
  require 'yaml'
7
7
 
8
8
  module Labkit
9
- module CoveredExperience
10
- Definition = Data.define(:covered_experience, :description, :feature_category, :urgency)
9
+ module UserExperienceSli
10
+ Definition = Data.define(:user_experience_id, :description, :feature_category, :urgency)
11
11
 
12
12
  class Registry
13
13
  extend Forwardable
14
14
 
15
- SCHEMA_PATH = File.expand_path('../../../config/covered_experiences/schema.json', __dir__)
15
+ SCHEMA_PATH = File.expand_path('../../../config/user_experience_slis/schema.json', __dir__)
16
16
 
17
17
  def_delegator :@experiences, :empty?
18
18
 
19
19
  # @param dir [String, Pathname] Directory path containing YAML file definitions
20
- # Defaults to 'config/covered_experiences' relative to the calling application's root
21
- def initialize(dir: File.join("config", "covered_experiences"))
20
+ # Defaults to 'config/user_experience_slis' relative to the calling application's root
21
+ def initialize(dir: File.join("config", "user_experience_slis"))
22
22
  @dir = Pathname.new(Dir.pwd).join(dir)
23
23
  @experiences = load_on_demand
24
24
  end
25
25
 
26
- # Retrieve a definition experience given a covered_experience_id.
26
+ # Retrieve a definition experience given a user_experience_id.
27
27
  #
28
- # @param covered_experience_id [String, Symbol] Covered experience identifier
28
+ # @param user_experience_id [String, Symbol] User experience SLI identifier
29
29
  # @return [Experience, nil] An experience if present, otherwise nil
30
- def [](covered_experience_id)
31
- @experiences[covered_experience_id.to_s]
30
+ def [](user_experience_id)
31
+ @experiences[user_experience_id.to_s]
32
32
  end
33
33
 
34
34
  private
@@ -49,7 +49,7 @@ module Labkit
49
49
  end
50
50
  end
51
51
 
52
- # Load a covered experience definition.
52
+ # Load a user experience SLI definition.
53
53
  #
54
54
  # @param experience_id [String] Experience identifier
55
55
  # @return [Experience, nil] Loaded experience or nil if not found/invalid
@@ -57,7 +57,7 @@ module Labkit
57
57
  file_path = @dir.join("#{experience_id}.yml")
58
58
 
59
59
  unless file_path.exist?
60
- warn("Invalid Covered Experience definition: #{experience_id}")
60
+ warn("Invalid User Experience definition: #{experience_id}")
61
61
  return nil
62
62
  end
63
63
 
@@ -78,7 +78,7 @@ module Labkit
78
78
  return nil unless content.is_a?(Hash)
79
79
 
80
80
  errors = JSON::Validator.fully_validate(schema, content)
81
- return Definition.new(covered_experience: experience_id, **content) if errors.empty?
81
+ return Definition.new(user_experience_id: experience_id, **content) if errors.empty?
82
82
 
83
83
  warn("Invalid schema for #{file_path}")
84
84
 
@@ -98,7 +98,7 @@ module Labkit
98
98
  end
99
99
 
100
100
  def logger
101
- Labkit::CoveredExperience.configuration.logger
101
+ Labkit::UserExperienceSli.configuration.logger
102
102
  end
103
103
  end
104
104
  end
@@ -1,26 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'labkit/covered_experience/current'
4
- require 'labkit/covered_experience/error'
5
- require 'labkit/covered_experience/experience'
6
- require 'labkit/covered_experience/null'
7
- require 'labkit/covered_experience/registry'
3
+ require 'labkit/user_experience_sli/current'
4
+ require 'labkit/user_experience_sli/error'
5
+ require 'labkit/user_experience_sli/experience'
6
+ require 'labkit/user_experience_sli/null'
7
+ require 'labkit/user_experience_sli/registry'
8
8
  require 'labkit/logging/json_logger'
9
9
 
10
10
  module Labkit
11
- # Labkit::CoveredExperience namespace module.
11
+ # Labkit::UserExperienceSli namespace module.
12
12
  #
13
- # This module is responsible for managing covered experiences, which are
13
+ # This module is responsible for managing user experience SLIs, which are
14
14
  # specific events or activities within the application that are measured
15
15
  # and reported for performance monitoring and analysis.
16
- module CoveredExperience
17
- # Configuration class for CoveredExperience
16
+ module UserExperienceSli
17
+ # Configuration class for UserExperienceSli
18
18
  class Configuration
19
19
  attr_accessor :logger, :registry_path
20
20
 
21
21
  def initialize
22
22
  @logger = Labkit::Logging::JsonLogger.new($stdout)
23
- @registry_path = File.join("config", "covered_experiences")
23
+ @registry_path = File.join("config", "user_experience_slis")
24
24
  end
25
25
  end
26
26
 
@@ -81,7 +81,7 @@ module Labkit
81
81
  def raise_or_null(experience_id)
82
82
  return Null.instance unless %w[development test].include?(ENV['RAILS_ENV'])
83
83
 
84
- raise(NotFoundError, "Covered Experience #{experience_id} not found in the registry")
84
+ raise(NotFoundError, "User Experience #{experience_id} not found in the registry")
85
85
  end
86
86
 
87
87
  def find_current(experience_id)
@@ -93,4 +93,9 @@ module Labkit
93
93
  end
94
94
  end
95
95
  end
96
+
97
+ # Backward compatibility alias for the old module name.
98
+ # This alias is kept to maintain compatibility with existing code.
99
+ # See: https://gitlab.com/gitlab-com/gl-infra/observability/team/-/issues/4347
100
+ CoveredExperience = UserExperienceSli
96
101
  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: 0.42.1
4
+ version: 0.42.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Newdigate
@@ -447,8 +447,8 @@ files:
447
447
  - LICENSE
448
448
  - README.md
449
449
  - Rakefile
450
- - config/covered_experiences/schema.json
451
- - config/covered_experiences/testing_sample.yml
450
+ - config/user_experience_slis/schema.json
451
+ - config/user_experience_slis/testing_sample.yml
452
452
  - gitlab-labkit.gemspec
453
453
  - lib/gitlab-labkit.rb
454
454
  - lib/labkit/context.rb
@@ -458,13 +458,6 @@ files:
458
458
  - lib/labkit/correlation/grpc/client_interceptor.rb
459
459
  - lib/labkit/correlation/grpc/grpc_common.rb
460
460
  - lib/labkit/correlation/grpc/server_interceptor.rb
461
- - lib/labkit/covered_experience.rb
462
- - lib/labkit/covered_experience/README.md
463
- - lib/labkit/covered_experience/current.rb
464
- - lib/labkit/covered_experience/error.rb
465
- - lib/labkit/covered_experience/experience.rb
466
- - lib/labkit/covered_experience/null.rb
467
- - lib/labkit/covered_experience/registry.rb
468
461
  - lib/labkit/excon_publisher.rb
469
462
  - lib/labkit/fields.rb
470
463
  - lib/labkit/fips.rb
@@ -487,18 +480,18 @@ files:
487
480
  - lib/labkit/middleware/sidekiq/context.rb
488
481
  - lib/labkit/middleware/sidekiq/context/client.rb
489
482
  - lib/labkit/middleware/sidekiq/context/server.rb
490
- - lib/labkit/middleware/sidekiq/covered_experience.rb
491
- - lib/labkit/middleware/sidekiq/covered_experience/client.rb
492
- - lib/labkit/middleware/sidekiq/covered_experience/server.rb
493
483
  - lib/labkit/middleware/sidekiq/server.rb
494
484
  - lib/labkit/middleware/sidekiq/tracing.rb
495
485
  - lib/labkit/middleware/sidekiq/tracing/client.rb
496
486
  - lib/labkit/middleware/sidekiq/tracing/server.rb
497
487
  - lib/labkit/middleware/sidekiq/tracing/sidekiq_common.rb
488
+ - lib/labkit/middleware/sidekiq/user_experience_sli.rb
489
+ - lib/labkit/middleware/sidekiq/user_experience_sli/client.rb
490
+ - lib/labkit/middleware/sidekiq/user_experience_sli/server.rb
498
491
  - lib/labkit/net_http_publisher.rb
499
492
  - lib/labkit/rspec/README.md
500
493
  - lib/labkit/rspec/matchers.rb
501
- - lib/labkit/rspec/matchers/covered_experience_matchers.rb
494
+ - lib/labkit/rspec/matchers/user_experience_matchers.rb
502
495
  - lib/labkit/system.rb
503
496
  - lib/labkit/tracing.rb
504
497
  - lib/labkit/tracing/abstract_instrumenter.rb
@@ -532,6 +525,13 @@ files:
532
525
  - lib/labkit/tracing/redis/redis_interceptor_helper.rb
533
526
  - lib/labkit/tracing/tracing_common.rb
534
527
  - lib/labkit/tracing/tracing_utils.rb
528
+ - lib/labkit/user_experience_sli.rb
529
+ - lib/labkit/user_experience_sli/README.md
530
+ - lib/labkit/user_experience_sli/current.rb
531
+ - lib/labkit/user_experience_sli/error.rb
532
+ - lib/labkit/user_experience_sli/experience.rb
533
+ - lib/labkit/user_experience_sli/null.rb
534
+ - lib/labkit/user_experience_sli/registry.rb
535
535
  - renovate.json
536
536
  - scripts/install-asdf-plugins.sh
537
537
  - scripts/prepare-dev-env.sh
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Labkit
4
- module CoveredExperience
5
- CoveredExperienceError = Class.new(StandardError)
6
- NotFoundError = Class.new(CoveredExperienceError)
7
- ReservedKeywordError = Class.new(CoveredExperienceError)
8
- end
9
- end
@@ -1,14 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Labkit
4
- module Middleware
5
- module Sidekiq
6
- # This module contains all the sidekiq middleware regarding covered
7
- # experiences
8
- module CoveredExperience
9
- autoload :Client, "labkit/middleware/sidekiq/covered_experience/client"
10
- autoload :Server, "labkit/middleware/sidekiq/covered_experience/server"
11
- end
12
- end
13
- end
14
- end