summaryrefslogtreecommitdiff
path: root/spec/lib/gitlab/metrics
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-05-20 14:34:42 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-05-20 14:34:42 +0000
commit9f46488805e86b1bc341ea1620b866016c2ce5ed (patch)
treef9748c7e287041e37d6da49e0a29c9511dc34768 /spec/lib/gitlab/metrics
parentdfc92d081ea0332d69c8aca2f0e745cb48ae5e6d (diff)
downloadgitlab-ce-9f46488805e86b1bc341ea1620b866016c2ce5ed.tar.gz
Add latest changes from gitlab-org/gitlab@13-0-stable-ee
Diffstat (limited to 'spec/lib/gitlab/metrics')
-rw-r--r--spec/lib/gitlab/metrics/background_transaction_spec.rb6
-rw-r--r--spec/lib/gitlab/metrics/dashboard/stages/grafana_formatter_spec.rb6
-rw-r--r--spec/lib/gitlab/metrics/dashboard/url_spec.rb32
-rw-r--r--spec/lib/gitlab/metrics/exporter/sidekiq_exporter_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/method_call_spec.rb19
-rw-r--r--spec/lib/gitlab/metrics/metric_spec.rb71
-rw-r--r--spec/lib/gitlab/metrics/rack_middleware_spec.rb25
-rw-r--r--spec/lib/gitlab/metrics/samplers/database_sampler_spec.rb49
-rw-r--r--spec/lib/gitlab/metrics/samplers/influx_sampler_spec.rb105
-rw-r--r--spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb32
-rw-r--r--spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb7
-rw-r--r--spec/lib/gitlab/metrics/subscribers/action_view_spec.rb6
-rw-r--r--spec/lib/gitlab/metrics/system_spec.rb117
-rw-r--r--spec/lib/gitlab/metrics/transaction_spec.rb165
-rw-r--r--spec/lib/gitlab/metrics/web_transaction_spec.rb144
15 files changed, 230 insertions, 556 deletions
diff --git a/spec/lib/gitlab/metrics/background_transaction_spec.rb b/spec/lib/gitlab/metrics/background_transaction_spec.rb
index d87d2c839ad..84f405d7369 100644
--- a/spec/lib/gitlab/metrics/background_transaction_spec.rb
+++ b/spec/lib/gitlab/metrics/background_transaction_spec.rb
@@ -7,12 +7,6 @@ describe Gitlab::Metrics::BackgroundTransaction do
subject { described_class.new(test_worker_class) }
- describe '#action' do
- it 'returns transaction action name' do
- expect(subject.action).to eq('TestWorker#perform')
- end
- end
-
describe '#label' do
it 'returns labels based on class name' do
expect(subject.labels).to eq(controller: 'TestWorker', action: 'perform')
diff --git a/spec/lib/gitlab/metrics/dashboard/stages/grafana_formatter_spec.rb b/spec/lib/gitlab/metrics/dashboard/stages/grafana_formatter_spec.rb
index e41004bb57e..5d4bd4512e3 100644
--- a/spec/lib/gitlab/metrics/dashboard/stages/grafana_formatter_spec.rb
+++ b/spec/lib/gitlab/metrics/dashboard/stages/grafana_formatter_spec.rb
@@ -9,9 +9,9 @@ describe Gitlab::Metrics::Dashboard::Stages::GrafanaFormatter do
let_it_be(:project) { create(:project, namespace: namespace, name: 'bar') }
describe '#transform!' do
- let(:grafana_dashboard) { JSON.parse(fixture_file('grafana/simplified_dashboard_response.json'), symbolize_names: true) }
- let(:datasource) { JSON.parse(fixture_file('grafana/datasource_response.json'), symbolize_names: true) }
- let(:expected_dashboard) { JSON.parse(fixture_file('grafana/expected_grafana_embed.json'), symbolize_names: true) }
+ let(:grafana_dashboard) { Gitlab::Json.parse(fixture_file('grafana/simplified_dashboard_response.json'), symbolize_names: true) }
+ let(:datasource) { Gitlab::Json.parse(fixture_file('grafana/datasource_response.json'), symbolize_names: true) }
+ let(:expected_dashboard) { Gitlab::Json.parse(fixture_file('grafana/expected_grafana_embed.json'), symbolize_names: true) }
subject(:dashboard) { described_class.new(project, {}, params).transform! }
diff --git a/spec/lib/gitlab/metrics/dashboard/url_spec.rb b/spec/lib/gitlab/metrics/dashboard/url_spec.rb
index 9ccd1c06d6b..75f9f99c8a6 100644
--- a/spec/lib/gitlab/metrics/dashboard/url_spec.rb
+++ b/spec/lib/gitlab/metrics/dashboard/url_spec.rb
@@ -3,17 +3,21 @@
require 'spec_helper'
describe Gitlab::Metrics::Dashboard::Url do
+ include Gitlab::Routing.url_helpers
+
describe '#metrics_regex' do
- let(:url) do
- Gitlab::Routing.url_helpers.metrics_namespace_project_environment_url(
+ let(:url_params) do
+ [
'foo',
'bar',
1,
- start: '2019-08-02T05:43:09.000Z',
- dashboard: 'config/prometheus/common_metrics.yml',
- group: 'awesome group',
- anchor: 'title'
- )
+ {
+ start: '2019-08-02T05:43:09.000Z',
+ dashboard: 'config/prometheus/common_metrics.yml',
+ group: 'awesome group',
+ anchor: 'title'
+ }
+ ]
end
let(:expected_params) do
@@ -29,12 +33,22 @@ describe Gitlab::Metrics::Dashboard::Url do
subject { described_class.metrics_regex }
- it_behaves_like 'regex which matches url when expected'
+ context 'for metrics route' do
+ let(:url) { metrics_namespace_project_environment_url(*url_params) }
+
+ it_behaves_like 'regex which matches url when expected'
+ end
+
+ context 'for metrics_dashboard route' do
+ let(:url) { metrics_dashboard_namespace_project_environment_url(*url_params) }
+
+ it_behaves_like 'regex which matches url when expected'
+ end
end
describe '#grafana_regex' do
let(:url) do
- Gitlab::Routing.url_helpers.namespace_project_grafana_api_metrics_dashboard_url(
+ namespace_project_grafana_api_metrics_dashboard_url(
'foo',
'bar',
start: '2019-08-02T05:43:09.000Z',
diff --git a/spec/lib/gitlab/metrics/exporter/sidekiq_exporter_spec.rb b/spec/lib/gitlab/metrics/exporter/sidekiq_exporter_spec.rb
index a415b6407d5..0b820fdbde9 100644
--- a/spec/lib/gitlab/metrics/exporter/sidekiq_exporter_spec.rb
+++ b/spec/lib/gitlab/metrics/exporter/sidekiq_exporter_spec.rb
@@ -53,7 +53,7 @@ describe Gitlab::Metrics::Exporter::SidekiqExporter do
.with(
class: described_class.to_s,
message: 'Cannot start sidekiq_exporter',
- exception: anything)
+ 'exception.message' => anything)
exporter.start
end
diff --git a/spec/lib/gitlab/metrics/method_call_spec.rb b/spec/lib/gitlab/metrics/method_call_spec.rb
index 3b5e04e2df5..229db67ec88 100644
--- a/spec/lib/gitlab/metrics/method_call_spec.rb
+++ b/spec/lib/gitlab/metrics/method_call_spec.rb
@@ -76,25 +76,6 @@ describe Gitlab::Metrics::MethodCall do
end
end
- describe '#to_metric' do
- it 'returns a Metric instance' do
- expect(method_call).to receive(:real_time).and_return(4.0001).twice
- expect(method_call).to receive(:cpu_time).and_return(3.0001)
-
- method_call.measure { 'foo' }
- metric = method_call.to_metric
-
- expect(metric).to be_an_instance_of(Gitlab::Metrics::Metric)
- expect(metric.series).to eq('rails_method_calls')
-
- expect(metric.values[:duration]).to eq(4000)
- expect(metric.values[:cpu_duration]).to eq(3000)
- expect(metric.values[:call_count]).to be_an(Integer)
-
- expect(metric.tags).to eq({ method: 'Foo#bar' })
- end
- end
-
describe '#above_threshold?' do
before do
allow(Gitlab::Metrics).to receive(:method_call_threshold).and_return(100)
diff --git a/spec/lib/gitlab/metrics/metric_spec.rb b/spec/lib/gitlab/metrics/metric_spec.rb
deleted file mode 100644
index 611b59231ba..00000000000
--- a/spec/lib/gitlab/metrics/metric_spec.rb
+++ /dev/null
@@ -1,71 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-describe Gitlab::Metrics::Metric do
- let(:metric) do
- described_class.new('foo', { number: 10 }, { host: 'localtoast' })
- end
-
- describe '#series' do
- subject { metric.series }
-
- it { is_expected.to eq('foo') }
- end
-
- describe '#values' do
- subject { metric.values }
-
- it { is_expected.to eq({ number: 10 }) }
- end
-
- describe '#tags' do
- subject { metric.tags }
-
- it { is_expected.to eq({ host: 'localtoast' }) }
- end
-
- describe '#type' do
- subject { metric.type }
-
- it { is_expected.to eq(:metric) }
- end
-
- describe '#event?' do
- it 'returns false for a regular metric' do
- expect(metric.event?).to eq(false)
- end
-
- it 'returns true for an event metric' do
- expect(metric).to receive(:type).and_return(:event)
-
- expect(metric.event?).to eq(true)
- end
- end
-
- describe '#to_hash' do
- it 'returns a Hash' do
- expect(metric.to_hash).to be_an_instance_of(Hash)
- end
-
- describe 'the returned Hash' do
- let(:hash) { metric.to_hash }
-
- it 'includes the series' do
- expect(hash[:series]).to eq('foo')
- end
-
- it 'includes the tags' do
- expect(hash[:tags]).to be_an_instance_of(Hash)
- end
-
- it 'includes the values' do
- expect(hash[:values]).to eq({ number: 10 })
- end
-
- it 'includes the timestamp' do
- expect(hash[:timestamp]).to be_an(Integer)
- end
- end
- end
-end
diff --git a/spec/lib/gitlab/metrics/rack_middleware_spec.rb b/spec/lib/gitlab/metrics/rack_middleware_spec.rb
index 1c1681cc5ab..dd1dbf7a1f4 100644
--- a/spec/lib/gitlab/metrics/rack_middleware_spec.rb
+++ b/spec/lib/gitlab/metrics/rack_middleware_spec.rb
@@ -10,10 +10,6 @@ describe Gitlab::Metrics::RackMiddleware do
let(:env) { { 'REQUEST_METHOD' => 'GET', 'REQUEST_URI' => '/foo' } }
describe '#call' do
- before do
- expect_any_instance_of(Gitlab::Metrics::Transaction).to receive(:finish)
- end
-
it 'tracks a transaction' do
expect(app).to receive(:call).with(env).and_return('yay')
@@ -36,26 +32,5 @@ describe Gitlab::Metrics::RackMiddleware do
it 'returns a Transaction' do
expect(transaction).to be_an_instance_of(Gitlab::Metrics::WebTransaction)
end
-
- it 'stores the request method and URI in the transaction as values' do
- expect(transaction.values[:request_method]).to eq('GET')
- expect(transaction.values[:request_uri]).to eq('/foo')
- end
-
- context "when URI includes sensitive parameters" do
- let(:env) do
- {
- 'REQUEST_METHOD' => 'GET',
- 'REQUEST_URI' => '/foo?private_token=my-token',
- 'PATH_INFO' => '/foo',
- 'QUERY_STRING' => 'private_token=my_token',
- 'action_dispatch.parameter_filter' => [:private_token]
- }
- end
-
- it 'stores the request URI with the sensitive parameters filtered' do
- expect(transaction.values[:request_uri]).to eq('/foo?private_token=[FILTERED]')
- end
- end
end
end
diff --git a/spec/lib/gitlab/metrics/samplers/database_sampler_spec.rb b/spec/lib/gitlab/metrics/samplers/database_sampler_spec.rb
new file mode 100644
index 00000000000..fdf3b5bd045
--- /dev/null
+++ b/spec/lib/gitlab/metrics/samplers/database_sampler_spec.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Metrics::Samplers::DatabaseSampler do
+ subject { described_class.new(described_class::SAMPLING_INTERVAL_SECONDS) }
+
+ describe '#sample' do
+ before do
+ described_class::METRIC_DESCRIPTIONS.each_key do |metric|
+ allow(subject.metrics[metric]).to receive(:set)
+ end
+ end
+
+ context 'for ActiveRecord::Base' do
+ let(:labels) do
+ {
+ class: 'ActiveRecord::Base',
+ host: Gitlab::Database.config['host'],
+ port: Gitlab::Database.config['port']
+ }
+ end
+
+ context 'when the database is connected' do
+ it 'samples connection pool statistics' do
+ expect(subject.metrics[:size]).to receive(:set).with(labels, a_value >= 1)
+ expect(subject.metrics[:connections]).to receive(:set).with(labels, a_value >= 1)
+ expect(subject.metrics[:busy]).to receive(:set).with(labels, a_value >= 1)
+ expect(subject.metrics[:dead]).to receive(:set).with(labels, a_value >= 0)
+ expect(subject.metrics[:waiting]).to receive(:set).with(labels, a_value >= 0)
+
+ subject.sample
+ end
+ end
+
+ context 'when the database is not connected' do
+ before do
+ allow(ActiveRecord::Base).to receive(:connected?).and_return(false)
+ end
+
+ it 'records no samples' do
+ expect(subject.metrics[:size]).not_to receive(:set).with(labels, anything)
+
+ subject.sample
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/metrics/samplers/influx_sampler_spec.rb b/spec/lib/gitlab/metrics/samplers/influx_sampler_spec.rb
deleted file mode 100644
index 939c057c342..00000000000
--- a/spec/lib/gitlab/metrics/samplers/influx_sampler_spec.rb
+++ /dev/null
@@ -1,105 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-describe Gitlab::Metrics::Samplers::InfluxSampler do
- let(:sampler) { described_class.new(5) }
-
- describe '#start' do
- it 'runs once and gathers a sample at a given interval' do
- expect(sampler).to receive(:sleep).with(a_kind_of(Numeric)).twice
- expect(sampler).to receive(:sample).once
- expect(sampler).to receive(:running).and_return(true, false)
-
- sampler.start.join
- end
- end
-
- describe '#sample' do
- it 'samples various statistics' do
- expect(sampler).to receive(:sample_memory_usage)
- expect(sampler).to receive(:sample_file_descriptors)
- expect(sampler).to receive(:flush)
-
- sampler.sample
- end
- end
-
- describe '#flush' do
- it 'schedules the metrics using Sidekiq' do
- expect(Gitlab::Metrics).to receive(:submit_metrics)
- .with([an_instance_of(Hash)])
-
- sampler.sample_memory_usage
- sampler.flush
- end
- end
-
- describe '#sample_memory_usage' do
- it 'adds a metric containing the memory usage' do
- expect(Gitlab::Metrics::System).to receive(:memory_usage)
- .and_return(9000)
-
- expect(sampler).to receive(:add_metric)
- .with(/memory_usage/, value: 9000)
- .and_call_original
-
- sampler.sample_memory_usage
- end
- end
-
- describe '#sample_file_descriptors' do
- it 'adds a metric containing the amount of open file descriptors' do
- expect(Gitlab::Metrics::System).to receive(:file_descriptor_count)
- .and_return(4)
-
- expect(sampler).to receive(:add_metric)
- .with(/file_descriptors/, value: 4)
- .and_call_original
-
- sampler.sample_file_descriptors
- end
- end
-
- describe '#add_metric' do
- it 'prefixes the series name for a Rails process' do
- expect(Gitlab::Runtime).to receive(:sidekiq?).and_return(false)
-
- expect(Gitlab::Metrics::Metric).to receive(:new)
- .with('rails_cats', { value: 10 }, {})
- .and_call_original
-
- sampler.add_metric('cats', value: 10)
- end
-
- it 'prefixes the series name for a Sidekiq process' do
- expect(Gitlab::Runtime).to receive(:sidekiq?).and_return(true)
-
- expect(Gitlab::Metrics::Metric).to receive(:new)
- .with('sidekiq_cats', { value: 10 }, {})
- .and_call_original
-
- sampler.add_metric('cats', value: 10)
- end
- end
-
- describe '#sleep_interval' do
- it 'returns a Numeric' do
- expect(sampler.sleep_interval).to be_a_kind_of(Numeric)
- end
-
- # Testing random behaviour is very hard, so treat this test as a basic smoke
- # test instead of a very accurate behaviour/unit test.
- it 'does not return the same interval twice in a row' do
- last = nil
-
- 100.times do
- interval = sampler.sleep_interval
-
- expect(interval).not_to eq(last)
-
- last = interval
- end
- end
- end
-end
diff --git a/spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb b/spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb
index 8c4071a7ed1..ead650a27f0 100644
--- a/spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb
+++ b/spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb
@@ -19,24 +19,38 @@ describe Gitlab::Metrics::Samplers::RubySampler do
end
describe '#sample' do
- it 'samples various statistics' do
- expect(Gitlab::Metrics::System).to receive(:cpu_time)
- expect(Gitlab::Metrics::System).to receive(:file_descriptor_count)
- expect(Gitlab::Metrics::System).to receive(:memory_usage)
- expect(Gitlab::Metrics::System).to receive(:max_open_file_descriptors)
- expect(sampler).to receive(:sample_gc)
+ it 'adds a metric containing the process resident memory bytes' do
+ expect(Gitlab::Metrics::System).to receive(:memory_usage_rss).and_return(9000)
+
+ expect(sampler.metrics[:process_resident_memory_bytes]).to receive(:set).with({}, 9000)
sampler.sample
end
- it 'adds a metric containing the process resident memory bytes' do
- expect(Gitlab::Metrics::System).to receive(:memory_usage).and_return(9000)
+ it 'adds a metric containing the process unique and proportional memory bytes' do
+ expect(Gitlab::Metrics::System).to receive(:memory_usage_uss_pss).and_return(uss: 9000, pss: 10_000)
- expect(sampler.metrics[:process_resident_memory_bytes]).to receive(:set).with({}, 9000)
+ expect(sampler.metrics[:process_unique_memory_bytes]).to receive(:set).with({}, 9000)
+ expect(sampler.metrics[:process_proportional_memory_bytes]).to receive(:set).with({}, 10_000)
sampler.sample
end
+ context 'when USS+PSS sampling is disabled via environment' do
+ before do
+ stub_env('enable_memory_uss_pss', "0")
+ end
+
+ it 'does not sample USS or PSS' do
+ expect(Gitlab::Metrics::System).not_to receive(:memory_usage_uss_pss)
+
+ expect(sampler.metrics[:process_unique_memory_bytes]).not_to receive(:set)
+ expect(sampler.metrics[:process_proportional_memory_bytes]).not_to receive(:set)
+
+ sampler.sample
+ end
+ end
+
it 'adds a metric containing the amount of open file descriptors' do
expect(Gitlab::Metrics::System).to receive(:file_descriptor_count)
.and_return(4)
diff --git a/spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb b/spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb
index bb95d5ab2ad..67336cf83e6 100644
--- a/spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb
+++ b/spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb
@@ -17,8 +17,6 @@ describe Gitlab::Metrics::SidekiqMiddleware do
expect_any_instance_of(Gitlab::Metrics::Transaction).to receive(:set)
.with(:sidekiq_queue_duration, instance_of(Float))
- expect_any_instance_of(Gitlab::Metrics::Transaction).to receive(:finish)
-
middleware.call(worker, message, :test) { nil }
end
@@ -32,8 +30,6 @@ describe Gitlab::Metrics::SidekiqMiddleware do
expect_any_instance_of(Gitlab::Metrics::Transaction).to receive(:set)
.with(:sidekiq_queue_duration, instance_of(Float))
- expect_any_instance_of(Gitlab::Metrics::Transaction).to receive(:finish)
-
middleware.call(worker, {}, :test) { nil }
end
@@ -46,9 +42,6 @@ describe Gitlab::Metrics::SidekiqMiddleware do
expect_any_instance_of(Gitlab::Metrics::Transaction)
.to receive(:add_event).with(:sidekiq_exception)
- expect_any_instance_of(Gitlab::Metrics::Transaction)
- .to receive(:finish)
-
expect { middleware.call(worker, message, :test) }
.to raise_error(RuntimeError)
end
diff --git a/spec/lib/gitlab/metrics/subscribers/action_view_spec.rb b/spec/lib/gitlab/metrics/subscribers/action_view_spec.rb
index 25c0e7b695a..857e54d3432 100644
--- a/spec/lib/gitlab/metrics/subscribers/action_view_spec.rb
+++ b/spec/lib/gitlab/metrics/subscribers/action_view_spec.rb
@@ -21,15 +21,9 @@ describe Gitlab::Metrics::Subscribers::ActionView do
describe '#render_template' do
it 'tracks rendering of a template' do
- values = { duration: 2.1 }
- tags = { view: 'app/views/x.html.haml' }
-
expect(transaction).to receive(:increment)
.with(:view_duration, 2.1)
- expect(transaction).to receive(:add_metric)
- .with(described_class::SERIES, values, tags)
-
subscriber.render_template(event)
end
diff --git a/spec/lib/gitlab/metrics/system_spec.rb b/spec/lib/gitlab/metrics/system_spec.rb
index a5aa80686fd..abb6a0096d6 100644
--- a/spec/lib/gitlab/metrics/system_spec.rb
+++ b/spec/lib/gitlab/metrics/system_spec.rb
@@ -3,33 +3,122 @@
require 'spec_helper'
describe Gitlab::Metrics::System do
- if File.exist?('/proc')
- describe '.memory_usage' do
- it "returns the process' memory usage in bytes" do
- expect(described_class.memory_usage).to be > 0
+ context 'when /proc files exist' do
+ # Fixtures pulled from:
+ # Linux carbon 5.3.0-7648-generic #41~1586789791~19.10~9593806-Ubuntu SMP Mon Apr 13 17:50:40 UTC x86_64 x86_64 x86_64 GNU/Linux
+ let(:proc_status) do
+ # most rows omitted for brevity
+ <<~SNIP
+ Name: less
+ VmHWM: 2468 kB
+ VmRSS: 2468 kB
+ RssAnon: 260 kB
+ SNIP
+ end
+
+ let(:proc_smaps_rollup) do
+ # full snapshot
+ <<~SNIP
+ Rss: 2564 kB
+ Pss: 503 kB
+ Pss_Anon: 312 kB
+ Pss_File: 191 kB
+ Pss_Shmem: 0 kB
+ Shared_Clean: 2100 kB
+ Shared_Dirty: 0 kB
+ Private_Clean: 152 kB
+ Private_Dirty: 312 kB
+ Referenced: 2564 kB
+ Anonymous: 312 kB
+ LazyFree: 0 kB
+ AnonHugePages: 0 kB
+ ShmemPmdMapped: 0 kB
+ Shared_Hugetlb: 0 kB
+ Private_Hugetlb: 0 kB
+ Swap: 0 kB
+ SwapPss: 0 kB
+ Locked: 0 kB
+ SNIP
+ end
+
+ let(:proc_limits) do
+ # full snapshot
+ <<~SNIP
+ Limit Soft Limit Hard Limit Units
+ Max cpu time unlimited unlimited seconds
+ Max file size unlimited unlimited bytes
+ Max data size unlimited unlimited bytes
+ Max stack size 8388608 unlimited bytes
+ Max core file size 0 unlimited bytes
+ Max resident set unlimited unlimited bytes
+ Max processes 126519 126519 processes
+ Max open files 1024 1048576 files
+ Max locked memory 67108864 67108864 bytes
+ Max address space unlimited unlimited bytes
+ Max file locks unlimited unlimited locks
+ Max pending signals 126519 126519 signals
+ Max msgqueue size 819200 819200 bytes
+ Max nice priority 0 0
+ Max realtime priority 0 0
+ Max realtime timeout unlimited unlimited us
+ SNIP
+ end
+
+ describe '.memory_usage_rss' do
+ it "returns the process' resident set size (RSS) in bytes" do
+ mock_existing_proc_file('/proc/self/status', proc_status)
+
+ expect(described_class.memory_usage_rss).to eq(2527232)
end
end
describe '.file_descriptor_count' do
it 'returns the amount of open file descriptors' do
- expect(described_class.file_descriptor_count).to be > 0
+ expect(Dir).to receive(:glob).and_return(['/some/path', '/some/other/path'])
+
+ expect(described_class.file_descriptor_count).to eq(2)
end
end
describe '.max_open_file_descriptors' do
it 'returns the max allowed open file descriptors' do
- expect(described_class.max_open_file_descriptors).to be > 0
+ mock_existing_proc_file('/proc/self/limits', proc_limits)
+
+ expect(described_class.max_open_file_descriptors).to eq(1024)
+ end
+ end
+
+ describe '.memory_usage_uss_pss' do
+ it "returns the process' unique and porportional set size (USS/PSS) in bytes" do
+ mock_existing_proc_file('/proc/self/smaps_rollup', proc_smaps_rollup)
+
+ # (Private_Clean (152 kB) + Private_Dirty (312 kB) + Private_Hugetlb (0 kB)) * 1024
+ expect(described_class.memory_usage_uss_pss).to eq(uss: 475136, pss: 515072)
end
end
- else
- describe '.memory_usage' do
- it 'returns 0.0' do
- expect(described_class.memory_usage).to eq(0.0)
+ end
+
+ context 'when /proc files do not exist' do
+ before do
+ mock_missing_proc_file
+ end
+
+ describe '.memory_usage_rss' do
+ it 'returns 0' do
+ expect(described_class.memory_usage_rss).to eq(0)
+ end
+ end
+
+ describe '.memory_usage_uss_pss' do
+ it "returns 0 for all components" do
+ expect(described_class.memory_usage_uss_pss).to eq(uss: 0, pss: 0)
end
end
describe '.file_descriptor_count' do
it 'returns 0' do
+ expect(Dir).to receive(:glob).and_return([])
+
expect(described_class.file_descriptor_count).to eq(0)
end
end
@@ -98,4 +187,12 @@ describe Gitlab::Metrics::System do
expect(described_class.thread_cpu_duration(start_time)).to be_nil
end
end
+
+ def mock_existing_proc_file(path, content)
+ allow(File).to receive(:foreach).with(path) { |_path, &block| content.each_line(&block) }
+ end
+
+ def mock_missing_proc_file
+ allow(File).to receive(:foreach).and_raise(Errno::ENOENT)
+ end
end
diff --git a/spec/lib/gitlab/metrics/transaction_spec.rb b/spec/lib/gitlab/metrics/transaction_spec.rb
index 08de2426c5a..cf46fa3e91c 100644
--- a/spec/lib/gitlab/metrics/transaction_spec.rb
+++ b/spec/lib/gitlab/metrics/transaction_spec.rb
@@ -4,7 +4,6 @@ require 'spec_helper'
describe Gitlab::Metrics::Transaction do
let(:transaction) { described_class.new }
- let(:metric) { transaction.metrics[0] }
let(:sensitive_tags) do
{
@@ -13,12 +12,6 @@ describe Gitlab::Metrics::Transaction do
}
end
- shared_examples 'tag filter' do |sane_tags|
- it 'filters potentially sensitive tags' do
- expect(metric.tags).to eq(sane_tags)
- end
- end
-
describe '#duration' do
it 'returns the duration of a transaction in seconds' do
transaction.run { }
@@ -61,25 +54,6 @@ describe Gitlab::Metrics::Transaction do
end
end
- describe '#add_metric' do
- it 'adds a metric to the transaction' do
- transaction.add_metric('foo', value: 1)
-
- expect(metric.series).to eq('rails_foo')
- expect(metric.tags).to eq({})
- expect(metric.values).to eq(value: 1)
- end
-
- context 'with sensitive tags' do
- before do
- transaction
- .add_metric('foo', { value: 1 }, **sensitive_tags.merge(sane: 'yes'))
- end
-
- it_behaves_like 'tag filter', sane: 'yes'
- end
- end
-
describe '#method_call_for' do
it 'returns a MethodCall' do
method = transaction.method_call_for('Foo#bar', :Foo, '#bar')
@@ -88,133 +62,23 @@ describe Gitlab::Metrics::Transaction do
end
end
- describe '#increment' do
- it 'increments a counter' do
- transaction.increment(:time, 1)
- transaction.increment(:time, 2)
-
- values = metric_values(time: 3)
-
- expect(transaction).to receive(:add_metric)
- .with('transactions', values, {})
-
- transaction.track_self
- end
- end
-
- describe '#set' do
- it 'sets a value' do
- transaction.set(:number, 10)
-
- values = metric_values(number: 10)
-
- expect(transaction).to receive(:add_metric)
- .with('transactions', values, {})
-
- transaction.track_self
- end
- end
-
- describe '#finish' do
- it 'tracks the transaction details and submits them to Sidekiq' do
- expect(transaction).to receive(:track_self)
- expect(transaction).to receive(:submit)
-
- transaction.finish
- end
- end
-
- describe '#track_self' do
- it 'adds a metric for the transaction itself' do
- values = metric_values
-
- expect(transaction).to receive(:add_metric)
- .with('transactions', values, {})
-
- transaction.track_self
- end
- end
-
- describe '#submit' do
- it 'submits the metrics to Sidekiq' do
- transaction.track_self
-
- expect(Gitlab::Metrics).to receive(:submit_metrics)
- .with([an_instance_of(Hash)])
-
- transaction.submit
- end
-
- it 'adds the action as a tag for every metric' do
- allow(transaction)
- .to receive(:labels)
- .and_return(controller: 'Foo', action: 'bar')
-
- transaction.track_self
-
- hash = {
- series: 'rails_transactions',
- tags: { action: 'Foo#bar' },
- values: metric_values,
- timestamp: a_kind_of(Integer)
- }
-
- expect(Gitlab::Metrics).to receive(:submit_metrics)
- .with([hash])
-
- transaction.submit
- end
-
- it 'does not add an action tag for events' do
- allow(transaction)
- .to receive(:labels)
- .and_return(controller: 'Foo', action: 'bar')
-
- transaction.add_event(:meow)
-
- hash = {
- series: 'events',
- tags: { event: :meow },
- values: { count: 1 },
- timestamp: a_kind_of(Integer)
- }
-
- expect(Gitlab::Metrics).to receive(:submit_metrics)
- .with([hash])
-
- transaction.submit
- end
- end
-
describe '#add_event' do
- it 'adds a metric' do
- transaction.add_event(:meow)
+ let(:prometheus_metric) { instance_double(Prometheus::Client::Counter, increment: nil) }
- expect(metric).to be_an_instance_of(Gitlab::Metrics::Metric)
+ before do
+ allow(described_class).to receive(:transaction_metric).and_return(prometheus_metric)
end
- it "does not prefix the metric's series name" do
- transaction.add_event(:meow)
-
- expect(metric.series).to eq(described_class::EVENT_SERIES)
- end
-
- it 'tracks a counter for every event' do
- transaction.add_event(:meow)
-
- expect(metric.values).to eq(count: 1)
- end
+ it 'adds a metric' do
+ expect(prometheus_metric).to receive(:increment)
- it 'tracks the event name' do
transaction.add_event(:meow)
-
- expect(metric.tags).to eq(event: :meow)
end
it 'allows tracking of custom tags' do
- transaction.add_event(:bau, animal: 'dog')
+ expect(prometheus_metric).to receive(:increment).with(hash_including(animal: "dog"))
- expect(metric.tags).to eq(event: :bau, animal: 'dog')
+ transaction.add_event(:bau, animal: 'dog')
end
context 'with sensitive tags' do
@@ -222,16 +86,11 @@ describe Gitlab::Metrics::Transaction do
transaction.add_event(:baubau, **sensitive_tags.merge(sane: 'yes'))
end
- it_behaves_like 'tag filter', event: :baubau, sane: 'yes'
- end
- end
-
- private
+ it 'filters tags' do
+ expect(prometheus_metric).not_to receive(:increment).with(hash_including(sensitive_tags))
- def metric_values(opts = {})
- {
- duration: 0.0,
- allocated_memory: a_kind_of(Numeric)
- }.merge(opts)
+ transaction.add_event(:baubau, **sensitive_tags.merge(sane: 'yes'))
+ end
+ end
end
end
diff --git a/spec/lib/gitlab/metrics/web_transaction_spec.rb b/spec/lib/gitlab/metrics/web_transaction_spec.rb
index 21a762dbf25..47f1bd3bd10 100644
--- a/spec/lib/gitlab/metrics/web_transaction_spec.rb
+++ b/spec/lib/gitlab/metrics/web_transaction_spec.rb
@@ -5,6 +5,11 @@ require 'spec_helper'
describe Gitlab::Metrics::WebTransaction do
let(:env) { {} }
let(:transaction) { described_class.new(env) }
+ let(:prometheus_metric) { double("prometheus metric") }
+
+ before do
+ allow(described_class).to receive(:transaction_metric).and_return(prometheus_metric)
+ end
describe '#duration' do
it 'returns the duration of a transaction in seconds' do
@@ -40,15 +45,6 @@ describe Gitlab::Metrics::WebTransaction do
end
end
- describe '#add_metric' do
- it 'adds a metric to the transaction' do
- expect(Gitlab::Metrics::Metric).to receive(:new)
- .with('rails_foo', { number: 10 }, {})
-
- transaction.add_metric('foo', number: 10)
- end
- end
-
describe '#method_call_for' do
it 'returns a MethodCall' do
method = transaction.method_call_for('Foo#bar', :Foo, '#bar')
@@ -59,101 +55,17 @@ describe Gitlab::Metrics::WebTransaction do
describe '#increment' do
it 'increments a counter' do
- transaction.increment(:time, 1)
- transaction.increment(:time, 2)
-
- values = { duration: 0.0, time: 3, allocated_memory: a_kind_of(Numeric) }
+ expect(prometheus_metric).to receive(:increment).with({}, 1)
- expect(transaction).to receive(:add_metric)
- .with('transactions', values, {})
-
- transaction.track_self
+ transaction.increment(:time, 1)
end
end
describe '#set' do
it 'sets a value' do
- transaction.set(:number, 10)
-
- values = {
- duration: 0.0,
- number: 10,
- allocated_memory: a_kind_of(Numeric)
- }
-
- expect(transaction).to receive(:add_metric)
- .with('transactions', values, {})
-
- transaction.track_self
- end
- end
-
- describe '#finish' do
- it 'tracks the transaction details and submits them to Sidekiq' do
- expect(transaction).to receive(:track_self)
- expect(transaction).to receive(:submit)
-
- transaction.finish
- end
- end
-
- describe '#track_self' do
- it 'adds a metric for the transaction itself' do
- values = {
- duration: transaction.duration,
- allocated_memory: a_kind_of(Numeric)
- }
-
- expect(transaction).to receive(:add_metric)
- .with('transactions', values, {})
-
- transaction.track_self
- end
- end
-
- describe '#submit' do
- it 'submits the metrics to Sidekiq' do
- transaction.track_self
-
- expect(Gitlab::Metrics).to receive(:submit_metrics)
- .with([an_instance_of(Hash)])
-
- transaction.submit
- end
+ expect(prometheus_metric).to receive(:set).with({}, 10)
- it 'adds the action as a tag for every metric' do
- allow(transaction).to receive(:labels).and_return(controller: 'Foo', action: 'bar')
- transaction.track_self
-
- hash = {
- series: 'rails_transactions',
- tags: { action: 'Foo#bar' },
- values: { duration: 0.0, allocated_memory: a_kind_of(Numeric) },
- timestamp: a_kind_of(Integer)
- }
-
- expect(Gitlab::Metrics).to receive(:submit_metrics)
- .with([hash])
-
- transaction.submit
- end
-
- it 'does not add an action tag for events' do
- allow(transaction).to receive(:labels).and_return(controller: 'Foo', action: 'bar')
-
- transaction.add_event(:meow)
-
- hash = {
- series: 'events',
- tags: { event: :meow },
- values: { count: 1 },
- timestamp: a_kind_of(Integer)
- }
-
- expect(Gitlab::Metrics).to receive(:submit_metrics)
- .with([hash])
-
- transaction.submit
+ transaction.set(:number, 10)
end
end
@@ -167,7 +79,6 @@ describe Gitlab::Metrics::WebTransaction do
end
it 'provides labels with the method and path of the route in the grape endpoint' do
expect(transaction.labels).to eq({ controller: 'Grape', action: 'GET /projects/:id/archive' })
- expect(transaction.action).to eq('Grape#GET /projects/:id/archive')
end
it 'does not provide labels if route infos are missing' do
@@ -177,7 +88,6 @@ describe Gitlab::Metrics::WebTransaction do
env['api.endpoint'] = endpoint
expect(transaction.labels).to eq({})
- expect(transaction.action).to be_nil
end
end
@@ -193,7 +103,6 @@ describe Gitlab::Metrics::WebTransaction do
it 'tags a transaction with the name and action of a controller' do
expect(transaction.labels).to eq({ controller: 'TestController', action: 'show' })
- expect(transaction.action).to eq('TestController#show')
end
context 'when the request content type is not :html' do
@@ -201,7 +110,6 @@ describe Gitlab::Metrics::WebTransaction do
it 'appends the mime type to the transaction action' do
expect(transaction.labels).to eq({ controller: 'TestController', action: 'show.json' })
- expect(transaction.action).to eq('TestController#show.json')
end
end
@@ -210,54 +118,26 @@ describe Gitlab::Metrics::WebTransaction do
it 'does not append the MIME type to the transaction action' do
expect(transaction.labels).to eq({ controller: 'TestController', action: 'show' })
- expect(transaction.action).to eq('TestController#show')
end
end
end
it 'returns no labels when no route information is present in env' do
expect(transaction.labels).to eq({})
- expect(transaction.action).to eq(nil)
end
end
describe '#add_event' do
it 'adds a metric' do
- transaction.add_event(:meow)
+ expect(prometheus_metric).to receive(:increment)
- expect(transaction.metrics[0]).to be_an_instance_of(Gitlab::Metrics::Metric)
- end
-
- it "does not prefix the metric's series name" do
transaction.add_event(:meow)
-
- metric = transaction.metrics[0]
-
- expect(metric.series).to eq(described_class::EVENT_SERIES)
- end
-
- it 'tracks a counter for every event' do
- transaction.add_event(:meow)
-
- metric = transaction.metrics[0]
-
- expect(metric.values).to eq(count: 1)
- end
-
- it 'tracks the event name' do
- transaction.add_event(:meow)
-
- metric = transaction.metrics[0]
-
- expect(metric.tags).to eq(event: :meow)
end
it 'allows tracking of custom tags' do
- transaction.add_event(:bau, animal: 'dog')
-
- metric = transaction.metrics[0]
+ expect(prometheus_metric).to receive(:increment).with(animal: "dog")
- expect(metric.tags).to eq(event: :bau, animal: 'dog')
+ transaction.add_event(:bau, animal: 'dog')
end
end
end