Commit 2dd3e3d7 authored by Matthias Käppler's avatar Matthias Käppler Committed by Sean McGivern

Allow sampler intervals to be configured via env

This is useful for development but also to more easily
change these values in production.
parent ae349032
---
title: Sampler intervals can now be configured via env vars
merge_request: 50625
author:
type: other
...@@ -61,3 +61,14 @@ half above the interval. For example, for a user defined interval of 15 seconds ...@@ -61,3 +61,14 @@ half above the interval. For example, for a user defined interval of 15 seconds
the actual interval can be anywhere between 7.5 and 22.5. The interval is the actual interval can be anywhere between 7.5 and 22.5. The interval is
re-generated for every sampling run instead of being generated one time and reused re-generated for every sampling run instead of being generated one time and reused
for the duration of the process' lifetime. for the duration of the process' lifetime.
User defined intervals can be specified by means of environment variables.
The following environment variables are recognized:
- `RUBY_SAMPLER_INTERVAL_SECONDS`
- `DATABASE_SAMPLER_INTERVAL_SECONDS`
- `ACTION_CABLE_SAMPLER_INTERVAL_SECONDS`
- `PUMA_SAMPLER_INTERVAL_SECONDS`
- `UNICORN_SAMPLER_INTERVAL_SECONDS`
- `THREADS_SAMPLER_INTERVAL_SECONDS`
- `GLOBAL_SEARCH_SAMPLER_INTERVAL_SECONDS`
...@@ -4,7 +4,7 @@ module Gitlab ...@@ -4,7 +4,7 @@ module Gitlab
module Metrics module Metrics
module Samplers module Samplers
class GlobalSearchSampler < BaseSampler class GlobalSearchSampler < BaseSampler
SAMPLING_INTERVAL_SECONDS = 60 DEFAULT_SAMPLING_INTERVAL_SECONDS = 60
def sample def sample
::Elastic::MetricsUpdateService.new.execute ::Elastic::MetricsUpdateService.new.execute
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe Gitlab::Metrics::Samplers::DatabaseSampler do RSpec.describe Gitlab::Metrics::Samplers::DatabaseSampler do
subject { described_class.new(described_class::SAMPLING_INTERVAL_SECONDS) } subject { described_class.new }
describe '#sample' do describe '#sample' do
before do before do
......
...@@ -5,15 +5,7 @@ require 'spec_helper' ...@@ -5,15 +5,7 @@ require 'spec_helper'
RSpec.describe Gitlab::Metrics::Samplers::GlobalSearchSampler do RSpec.describe Gitlab::Metrics::Samplers::GlobalSearchSampler do
subject { described_class.new } subject { described_class.new }
describe '#interval' do it_behaves_like 'metrics sampler', 'GLOBAL_SEARCH_SAMPLER'
it 'samples every sixty seconds by default' do
expect(subject.interval).to eq(60)
end
it 'samples at other intervals if requested' do
expect(described_class.new(11).interval).to eq(11)
end
end
describe '#sample' do describe '#sample' do
it 'invokes the Elastic::MetricsUpdateService' do it 'invokes the Elastic::MetricsUpdateService' do
......
...@@ -4,9 +4,9 @@ module Gitlab ...@@ -4,9 +4,9 @@ module Gitlab
module Metrics module Metrics
module Samplers module Samplers
class ActionCableSampler < BaseSampler class ActionCableSampler < BaseSampler
SAMPLING_INTERVAL_SECONDS = 5 DEFAULT_SAMPLING_INTERVAL_SECONDS = 5
def initialize(interval = SAMPLING_INTERVAL_SECONDS, action_cable: ::ActionCable.server) def initialize(interval = nil, action_cable: ::ActionCable.server)
super(interval) super(interval)
@action_cable = action_cable @action_cable = action_cable
end end
......
...@@ -9,7 +9,9 @@ module Gitlab ...@@ -9,7 +9,9 @@ module Gitlab
attr_reader :interval attr_reader :interval
# interval - The sampling interval in seconds. # interval - The sampling interval in seconds.
def initialize(interval = self.class::SAMPLING_INTERVAL_SECONDS) def initialize(interval = nil)
interval ||= ENV[interval_env_key]&.to_i
interval ||= self.class::DEFAULT_SAMPLING_INTERVAL_SECONDS
interval_half = interval.to_f / 2 interval_half = interval.to_f / 2
@interval = interval @interval = interval
...@@ -50,6 +52,14 @@ module Gitlab ...@@ -50,6 +52,14 @@ module Gitlab
attr_reader :running attr_reader :running
def sampler_class
self.class.name.demodulize
end
def interval_env_key
"#{sampler_class.underscore.upcase}_INTERVAL_SECONDS"
end
def start_working def start_working
@running = true @running = true
......
...@@ -4,7 +4,7 @@ module Gitlab ...@@ -4,7 +4,7 @@ module Gitlab
module Metrics module Metrics
module Samplers module Samplers
class DatabaseSampler < BaseSampler class DatabaseSampler < BaseSampler
SAMPLING_INTERVAL_SECONDS = 5 DEFAULT_SAMPLING_INTERVAL_SECONDS = 5
METRIC_PREFIX = 'gitlab_database_connection_pool_' METRIC_PREFIX = 'gitlab_database_connection_pool_'
......
...@@ -4,7 +4,7 @@ module Gitlab ...@@ -4,7 +4,7 @@ module Gitlab
module Metrics module Metrics
module Samplers module Samplers
class PumaSampler < BaseSampler class PumaSampler < BaseSampler
SAMPLING_INTERVAL_SECONDS = 5 DEFAULT_SAMPLING_INTERVAL_SECONDS = 5
def metrics def metrics
@metrics ||= init_metrics @metrics ||= init_metrics
......
...@@ -6,7 +6,7 @@ module Gitlab ...@@ -6,7 +6,7 @@ module Gitlab
module Metrics module Metrics
module Samplers module Samplers
class RubySampler < BaseSampler class RubySampler < BaseSampler
SAMPLING_INTERVAL_SECONDS = 60 DEFAULT_SAMPLING_INTERVAL_SECONDS = 60
GC_REPORT_BUCKETS = [0.005, 0.01, 0.02, 0.04, 0.07, 0.1, 0.5].freeze GC_REPORT_BUCKETS = [0.005, 0.01, 0.02, 0.04, 0.07, 0.1, 0.5].freeze
def initialize(*) def initialize(*)
......
...@@ -4,7 +4,7 @@ module Gitlab ...@@ -4,7 +4,7 @@ module Gitlab
module Metrics module Metrics
module Samplers module Samplers
class ThreadsSampler < BaseSampler class ThreadsSampler < BaseSampler
SAMPLING_INTERVAL_SECONDS = 5 DEFAULT_SAMPLING_INTERVAL_SECONDS = 5
KNOWN_PUMA_THREAD_NAMES = ['puma worker check pipe', 'puma server', KNOWN_PUMA_THREAD_NAMES = ['puma worker check pipe', 'puma server',
'puma threadpool reaper', 'puma threadpool trimmer', 'puma threadpool reaper', 'puma threadpool trimmer',
'puma worker check pipe', 'puma stat payload'].freeze 'puma worker check pipe', 'puma stat payload'].freeze
......
...@@ -4,6 +4,8 @@ module Gitlab ...@@ -4,6 +4,8 @@ module Gitlab
module Metrics module Metrics
module Samplers module Samplers
class UnicornSampler < BaseSampler class UnicornSampler < BaseSampler
DEFAULT_SAMPLING_INTERVAL_SECONDS = 5
def metrics def metrics
@metrics ||= init_metrics @metrics ||= init_metrics
end end
......
...@@ -7,15 +7,7 @@ RSpec.describe Gitlab::Metrics::Samplers::ActionCableSampler do ...@@ -7,15 +7,7 @@ RSpec.describe Gitlab::Metrics::Samplers::ActionCableSampler do
subject { described_class.new(action_cable: action_cable) } subject { described_class.new(action_cable: action_cable) }
describe '#interval' do it_behaves_like 'metrics sampler', 'ACTION_CABLE_SAMPLER'
it 'samples every five seconds by default' do
expect(subject.interval).to eq(5)
end
it 'samples at other intervals if requested' do
expect(described_class.new(11).interval).to eq(11)
end
end
describe '#sample' do describe '#sample' do
let(:pool) { instance_double(Concurrent::ThreadPoolExecutor) } let(:pool) { instance_double(Concurrent::ThreadPoolExecutor) }
......
...@@ -5,15 +5,7 @@ require 'spec_helper' ...@@ -5,15 +5,7 @@ require 'spec_helper'
RSpec.describe Gitlab::Metrics::Samplers::DatabaseSampler do RSpec.describe Gitlab::Metrics::Samplers::DatabaseSampler do
subject { described_class.new } subject { described_class.new }
describe '#interval' do it_behaves_like 'metrics sampler', 'DATABASE_SAMPLER'
it 'samples every five seconds by default' do
expect(subject.interval).to eq(5)
end
it 'samples at other intervals if requested' do
expect(described_class.new(11).interval).to eq(11)
end
end
describe '#sample' do describe '#sample' do
before do before do
......
...@@ -11,15 +11,7 @@ RSpec.describe Gitlab::Metrics::Samplers::PumaSampler do ...@@ -11,15 +11,7 @@ RSpec.describe Gitlab::Metrics::Samplers::PumaSampler do
allow(Gitlab::Metrics::NullMetric).to receive(:instance).and_return(null_metric) allow(Gitlab::Metrics::NullMetric).to receive(:instance).and_return(null_metric)
end end
describe '#interval' do it_behaves_like 'metrics sampler', 'PUMA_SAMPLER'
it 'samples every five seconds by default' do
expect(subject.interval).to eq(5)
end
it 'samples at other intervals if requested' do
expect(described_class.new(11).interval).to eq(11)
end
end
describe '#sample' do describe '#sample' do
before do before do
......
...@@ -10,6 +10,8 @@ RSpec.describe Gitlab::Metrics::Samplers::RubySampler do ...@@ -10,6 +10,8 @@ RSpec.describe Gitlab::Metrics::Samplers::RubySampler do
allow(Gitlab::Metrics::NullMetric).to receive(:instance).and_return(null_metric) allow(Gitlab::Metrics::NullMetric).to receive(:instance).and_return(null_metric)
end end
it_behaves_like 'metrics sampler', 'RUBY_SAMPLER'
describe '#initialize' do describe '#initialize' do
it 'sets process_start_time_seconds' do it 'sets process_start_time_seconds' do
freeze_time do freeze_time do
...@@ -18,16 +20,6 @@ RSpec.describe Gitlab::Metrics::Samplers::RubySampler do ...@@ -18,16 +20,6 @@ RSpec.describe Gitlab::Metrics::Samplers::RubySampler do
end end
end end
describe '#interval' do
it 'samples every sixty seconds by default' do
expect(subject.interval).to eq(60)
end
it 'samples at other intervals if requested' do
expect(described_class.new(11).interval).to eq(11)
end
end
describe '#sample' do describe '#sample' do
it 'adds a metric containing the process resident memory bytes' do it 'adds a metric containing the process resident memory bytes' do
expect(Gitlab::Metrics::System).to receive(:memory_usage_rss).and_return(9000) expect(Gitlab::Metrics::System).to receive(:memory_usage_rss).and_return(9000)
......
...@@ -5,15 +5,7 @@ require 'spec_helper' ...@@ -5,15 +5,7 @@ require 'spec_helper'
RSpec.describe Gitlab::Metrics::Samplers::ThreadsSampler do RSpec.describe Gitlab::Metrics::Samplers::ThreadsSampler do
subject { described_class.new } subject { described_class.new }
describe '#interval' do it_behaves_like 'metrics sampler', 'THREADS_SAMPLER'
it 'samples every five seconds by default' do
expect(subject.interval).to eq(5)
end
it 'samples at other intervals if requested' do
expect(described_class.new(11).interval).to eq(11)
end
end
describe '#sample' do describe '#sample' do
before do before do
......
...@@ -5,6 +5,8 @@ require 'spec_helper' ...@@ -5,6 +5,8 @@ require 'spec_helper'
RSpec.describe Gitlab::Metrics::Samplers::UnicornSampler do RSpec.describe Gitlab::Metrics::Samplers::UnicornSampler do
subject { described_class.new(1.second) } subject { described_class.new(1.second) }
it_behaves_like 'metrics sampler', 'UNICORN_SAMPLER'
describe '#sample' do describe '#sample' do
let(:unicorn) { Module.new } let(:unicorn) { Module.new }
let(:raindrops) { double('raindrops') } let(:raindrops) { double('raindrops') }
......
# frozen_string_literal: true
RSpec.shared_examples 'metrics sampler' do |env_prefix|
context 'when sampling interval is passed explicitly' do
subject { described_class.new(42) }
specify { expect(subject.interval).to eq(42) }
end
context 'when sampling interval is passed through the environment' do
subject { described_class.new }
before do
stub_env("#{env_prefix}_INTERVAL_SECONDS", '42')
end
specify { expect(subject.interval).to eq(42) }
end
context 'when no sampling interval is passed anywhere' do
subject { described_class.new }
it 'uses the hardcoded default' do
expect(subject.interval).to eq(described_class::DEFAULT_SAMPLING_INTERVAL_SECONDS)
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment