(POOLER-178) Target Stats for api & manager

Ensure that the correct stats are registered for the Manager and the api
respectively. E.g. all checkout counters are for the api only, whereas
clone times belong to the manager.

Also new ondemand functionality stats weren't registered, so add these
along with missing delete stats.
This commit is contained in:
John O'Connor 2020-06-25 19:44:26 +01:00
parent 8ed8c43970
commit a21d8c5642
14 changed files with 128 additions and 28 deletions

View file

@ -16,15 +16,15 @@ metrics = Vmpooler::Metrics.init(logger, config)
torun_threads = [] torun_threads = []
if ARGV.count == 0 if ARGV.count == 0
torun = ['api', 'manager'] torun = %i[api manager]
else else
torun = [] torun = []
torun << 'api' if ARGV.include? 'api' torun << :api if ARGV.include? 'api'
torun << 'manager' if ARGV.include? 'manager' torun << :manager if ARGV.include? 'manager'
exit(2) if torun.empty? exit(2) if torun.empty?
end end
if torun.include? 'api' if torun.include? :api
api = Thread.new do api = Thread.new do
redis = Vmpooler.new_redis(redis_host, redis_port, redis_password) redis = Vmpooler.new_redis(redis_host, redis_port, redis_password)
Vmpooler::API.execute(torun, config, redis, metrics) Vmpooler::API.execute(torun, config, redis, metrics)
@ -38,7 +38,7 @@ elsif metrics.respond_to?(:setup_prometheus_metrics)
torun_threads << prometheus_only_api torun_threads << prometheus_only_api
end end
if torun.include? 'manager' if torun.include? :manager
manager = Thread.new do manager = Thread.new do
Vmpooler::PoolManager.new( Vmpooler::PoolManager.new(
config, config,

View file

@ -33,7 +33,7 @@ module Vmpooler
if metrics.respond_to?(:setup_prometheus_metrics) if metrics.respond_to?(:setup_prometheus_metrics)
# Prometheus metrics are only setup if actually specified # Prometheus metrics are only setup if actually specified
# in the config file. # in the config file.
metrics.setup_prometheus_metrics metrics.setup_prometheus_metrics(torun)
# Using customised collector that filters out hostnames on API paths # Using customised collector that filters out hostnames on API paths
require 'vmpooler/metrics/promstats/collector_middleware' require 'vmpooler/metrics/promstats/collector_middleware'
@ -42,7 +42,7 @@ module Vmpooler
use Prometheus::Middleware::Exporter, path: metrics.endpoint use Prometheus::Middleware::Exporter, path: metrics.endpoint
end end
if torun.include? 'api' if torun.include? :api
use Vmpooler::Dashboard use Vmpooler::Dashboard
use Vmpooler::API::Dashboard use Vmpooler::API::Dashboard
use Vmpooler::API::Reroute use Vmpooler::API::Reroute

View file

@ -339,7 +339,7 @@ module Vmpooler
payload&.each do |poolname, count| payload&.each do |poolname, count|
next unless count.to_i > config['max_ondemand_instances_per_request'] next unless count.to_i > config['max_ondemand_instances_per_request']
metrics.increment('ondemandrequest.toomanyrequests.' + poolname) metrics.increment('ondemandrequest_fail.toomanyrequests.' + poolname)
return true return true
end end
false false
@ -363,7 +363,7 @@ module Vmpooler
if backend.exists?("vmpooler__odrequest__#{request_id}") if backend.exists?("vmpooler__odrequest__#{request_id}")
result['message'] = "request_id '#{request_id}' has already been created" result['message'] = "request_id '#{request_id}' has already been created"
status 409 status 409
metrics.increment('ondemandrequest.generate.duplicaterequests') metrics.increment('ondemandrequest_generate.duplicaterequests')
return result return result
end end
@ -387,7 +387,7 @@ module Vmpooler
result['domain'] = config['domain'] if config['domain'] result['domain'] = config['domain'] if config['domain']
result[:ok] = true result[:ok] = true
metrics.increment('ondemandrequest.generate.success') metrics.increment('ondemandrequest_generate.success')
result result
end end
@ -825,12 +825,12 @@ module Vmpooler
else else
result[:bad_templates] = invalid result[:bad_templates] = invalid
invalid.each do |bad_template| invalid.each do |bad_template|
metrics.increment('ondemandrequest.invalid.' + bad_template) metrics.increment('ondemandrequest_fail.invalid.' + bad_template)
end end
status 404 status 404
end end
else else
metrics.increment('ondemandrequest.invalid.unknown') metrics.increment('ondemandrequest_fail.invalid.unknown')
status 404 status 404
end end
rescue JSON::ParserError rescue JSON::ParserError
@ -860,12 +860,12 @@ module Vmpooler
else else
result[:bad_templates] = invalid result[:bad_templates] = invalid
invalid.each do |bad_template| invalid.each do |bad_template|
metrics.increment('ondemandrequest.invalid.' + bad_template) metrics.increment('ondemandrequest_fail.invalid.' + bad_template)
end end
status 404 status 404
end end
else else
metrics.increment('ondemandrequest.invalid.unknown') metrics.increment('ondemandrequest_fail.invalid.unknown')
status 404 status 404
end end
@ -1154,8 +1154,9 @@ module Vmpooler
status 200 status 200
result['ok'] = true result['ok'] = true
metrics.increment('delete.success')
else else
metrics.increment('delete.srem.failed') metrics.increment('delete.failed')
end end
end end

View file

@ -36,6 +36,7 @@ module Vmpooler
{ {
errors: { errors: {
mtype: M_COUNTER, mtype: M_COUNTER,
torun: %i[manager],
docstring: 'Count of errors for pool', docstring: 'Count of errors for pool',
prom_metric_prefix: "#{@metrics_prefix}_errors", prom_metric_prefix: "#{@metrics_prefix}_errors",
metric_suffixes: { metric_suffixes: {
@ -47,36 +48,42 @@ module Vmpooler
}, },
user: { user: {
mtype: M_COUNTER, mtype: M_COUNTER,
torun: %i[manager],
docstring: 'Number of pool instances this user created created', docstring: 'Number of pool instances this user created created',
prom_metric_prefix: "#{@metrics_prefix}_user", prom_metric_prefix: "#{@metrics_prefix}_user",
param_labels: %i[user poolname] param_labels: %i[user poolname]
}, },
usage_litmus: { usage_litmus: {
mtype: M_COUNTER, mtype: M_COUNTER,
torun: %i[manager],
docstring: 'Pools by Litmus job usage', docstring: 'Pools by Litmus job usage',
prom_metric_prefix: "#{@metrics_prefix}_usage_litmus", prom_metric_prefix: "#{@metrics_prefix}_usage_litmus",
param_labels: %i[user poolname] param_labels: %i[user poolname]
}, },
usage_jenkins_instance: { usage_jenkins_instance: {
mtype: M_COUNTER, mtype: M_COUNTER,
torun: %i[manager],
docstring: 'Pools by Jenkins instance usage', docstring: 'Pools by Jenkins instance usage',
prom_metric_prefix: "#{@metrics_prefix}_usage_jenkins_instance", prom_metric_prefix: "#{@metrics_prefix}_usage_jenkins_instance",
param_labels: %i[jenkins_instance value_stream poolname] param_labels: %i[jenkins_instance value_stream poolname]
}, },
usage_branch_project: { usage_branch_project: {
mtype: M_COUNTER, mtype: M_COUNTER,
torun: %i[manager],
docstring: 'Pools by branch/project usage', docstring: 'Pools by branch/project usage',
prom_metric_prefix: "#{@metrics_prefix}_usage_branch_project", prom_metric_prefix: "#{@metrics_prefix}_usage_branch_project",
param_labels: %i[branch project poolname] param_labels: %i[branch project poolname]
}, },
usage_job_component: { usage_job_component: {
mtype: M_COUNTER, mtype: M_COUNTER,
torun: %i[manager],
docstring: 'Pools by job/component usage', docstring: 'Pools by job/component usage',
prom_metric_prefix: "#{@metrics_prefix}_usage_job_component", prom_metric_prefix: "#{@metrics_prefix}_usage_job_component",
param_labels: %i[job_name component_to_test poolname] param_labels: %i[job_name component_to_test poolname]
}, },
checkout: { checkout: {
mtype: M_COUNTER, mtype: M_COUNTER,
torun: %i[api],
docstring: 'Pool checkout counts', docstring: 'Pool checkout counts',
prom_metric_prefix: "#{@metrics_prefix}_checkout", prom_metric_prefix: "#{@metrics_prefix}_checkout",
metric_suffixes: { metric_suffixes: {
@ -87,8 +94,42 @@ module Vmpooler
}, },
param_labels: %i[poolname] param_labels: %i[poolname]
}, },
delete: {
mtype: M_COUNTER,
torun: %i[api],
docstring: 'Delete machine',
prom_metric_prefix: "#{@metrics_prefix}_delete",
metric_suffixes: {
success: 'succeeded',
failed: 'failed'
},
param_labels: []
},
ondemandrequest_generate: {
mtype: M_COUNTER,
torun: %i[api],
docstring: 'Ondemand request',
prom_metric_prefix: "#{@metrics_prefix}_ondemandrequest_generate",
metric_suffixes: {
duplicaterequests: 'failed duplicate request',
success: 'succeeded'
},
param_labels: []
},
ondemandrequest_fail: {
mtype: M_COUNTER,
torun: %i[api],
docstring: 'Ondemand request failure',
prom_metric_prefix: "#{@metrics_prefix}_ondemandrequest_fail",
metric_suffixes: {
toomanyrequests: 'too many requests',
invalid: 'invalid poolname'
},
param_labels: %i[poolname]
},
config: { config: {
mtype: M_COUNTER, mtype: M_COUNTER,
torun: %i[api],
docstring: 'vmpooler pool configuration request', docstring: 'vmpooler pool configuration request',
prom_metric_prefix: "#{@metrics_prefix}_config", prom_metric_prefix: "#{@metrics_prefix}_config",
metric_suffixes: { invalid: 'Invalid' }, metric_suffixes: { invalid: 'Invalid' },
@ -96,6 +137,7 @@ module Vmpooler
}, },
poolreset: { poolreset: {
mtype: M_COUNTER, mtype: M_COUNTER,
torun: %i[api],
docstring: 'Pool reset counter', docstring: 'Pool reset counter',
prom_metric_prefix: "#{@metrics_prefix}_poolreset", prom_metric_prefix: "#{@metrics_prefix}_poolreset",
metric_suffixes: { invalid: 'Invalid Pool' }, metric_suffixes: { invalid: 'Invalid Pool' },
@ -103,6 +145,7 @@ module Vmpooler
}, },
connect: { connect: {
mtype: M_COUNTER, mtype: M_COUNTER,
torun: %i[manager],
docstring: 'vmpooler connect (to vSphere)', docstring: 'vmpooler connect (to vSphere)',
prom_metric_prefix: "#{@metrics_prefix}_connect", prom_metric_prefix: "#{@metrics_prefix}_connect",
metric_suffixes: { metric_suffixes: {
@ -113,42 +156,49 @@ module Vmpooler
}, },
migrate_from: { migrate_from: {
mtype: M_COUNTER, mtype: M_COUNTER,
torun: %i[manager],
docstring: 'vmpooler machine migrated from', docstring: 'vmpooler machine migrated from',
prom_metric_prefix: "#{@metrics_prefix}_migrate_from", prom_metric_prefix: "#{@metrics_prefix}_migrate_from",
param_labels: %i[host_name] param_labels: %i[host_name]
}, },
migrate_to: { migrate_to: {
mtype: M_COUNTER, mtype: M_COUNTER,
torun: %i[manager],
docstring: 'vmpooler machine migrated to', docstring: 'vmpooler machine migrated to',
prom_metric_prefix: "#{@metrics_prefix}_migrate_to", prom_metric_prefix: "#{@metrics_prefix}_migrate_to",
param_labels: %i[host_name] param_labels: %i[host_name]
}, },
api_vm: { api_vm: {
mtype: M_COUNTER, mtype: M_COUNTER,
torun: %i[api],
docstring: 'Total number of HTTP request/sub-operations handled by the Rack application under the /vm endpoint', docstring: 'Total number of HTTP request/sub-operations handled by the Rack application under the /vm endpoint',
prom_metric_prefix: "#{@metrics_prefix}_http_requests_vm_total", prom_metric_prefix: "#{@metrics_prefix}_http_requests_vm_total",
param_labels: %i[method subpath operation] param_labels: %i[method subpath operation]
}, },
ready: { ready: {
mtype: M_GAUGE, mtype: M_GAUGE,
torun: %i[manager],
docstring: 'vmpooler number of machines in ready State', docstring: 'vmpooler number of machines in ready State',
prom_metric_prefix: "#{@metrics_prefix}_ready", prom_metric_prefix: "#{@metrics_prefix}_ready",
param_labels: %i[poolname] param_labels: %i[poolname]
}, },
running: { running: {
mtype: M_GAUGE, mtype: M_GAUGE,
torun: %i[manager],
docstring: 'vmpooler number of machines running', docstring: 'vmpooler number of machines running',
prom_metric_prefix: "#{@metrics_prefix}_running", prom_metric_prefix: "#{@metrics_prefix}_running",
param_labels: %i[poolname] param_labels: %i[poolname]
}, },
connection_available: { connection_available: {
mtype: M_GAUGE, mtype: M_GAUGE,
torun: %i[manager],
docstring: 'vmpooler redis connections available', docstring: 'vmpooler redis connections available',
prom_metric_prefix: "#{@metrics_prefix}_connection_available", prom_metric_prefix: "#{@metrics_prefix}_connection_available",
param_labels: %i[type provider] param_labels: %i[type provider]
}, },
time_to_ready_state: { time_to_ready_state: {
mtype: M_HISTOGRAM, mtype: M_HISTOGRAM,
torun: %i[manager],
buckets: POOLER_TIME_BUCKETS, buckets: POOLER_TIME_BUCKETS,
docstring: 'Time taken for machine to read ready state for pool', docstring: 'Time taken for machine to read ready state for pool',
prom_metric_prefix: "#{@metrics_prefix}_time_to_ready_state", prom_metric_prefix: "#{@metrics_prefix}_time_to_ready_state",
@ -156,6 +206,7 @@ module Vmpooler
}, },
migrate: { migrate: {
mtype: M_HISTOGRAM, mtype: M_HISTOGRAM,
torun: %i[manager],
buckets: POOLER_TIME_BUCKETS, buckets: POOLER_TIME_BUCKETS,
docstring: 'vmpooler time taken to migrate machine for pool', docstring: 'vmpooler time taken to migrate machine for pool',
prom_metric_prefix: "#{@metrics_prefix}_migrate", prom_metric_prefix: "#{@metrics_prefix}_migrate",
@ -163,6 +214,7 @@ module Vmpooler
}, },
clone: { clone: {
mtype: M_HISTOGRAM, mtype: M_HISTOGRAM,
torun: %i[manager],
buckets: POOLER_TIME_BUCKETS, buckets: POOLER_TIME_BUCKETS,
docstring: 'vmpooler time taken to clone machine', docstring: 'vmpooler time taken to clone machine',
prom_metric_prefix: "#{@metrics_prefix}_clone", prom_metric_prefix: "#{@metrics_prefix}_clone",
@ -170,6 +222,7 @@ module Vmpooler
}, },
destroy: { destroy: {
mtype: M_HISTOGRAM, mtype: M_HISTOGRAM,
torun: %i[manager],
buckets: POOLER_TIME_BUCKETS, buckets: POOLER_TIME_BUCKETS,
docstring: 'vmpooler time taken to destroy machine', docstring: 'vmpooler time taken to destroy machine',
prom_metric_prefix: "#{@metrics_prefix}_destroy", prom_metric_prefix: "#{@metrics_prefix}_destroy",
@ -177,6 +230,7 @@ module Vmpooler
}, },
connection_waited: { connection_waited: {
mtype: M_HISTOGRAM, mtype: M_HISTOGRAM,
torun: %i[manager],
buckets: REDIS_CONNECT_BUCKETS, buckets: REDIS_CONNECT_BUCKETS,
docstring: 'vmpooler redis connection wait time', docstring: 'vmpooler redis connection wait time',
prom_metric_prefix: "#{@metrics_prefix}_connection_waited", prom_metric_prefix: "#{@metrics_prefix}_connection_waited",
@ -222,9 +276,12 @@ module Vmpooler
# Top level method to register all the prometheus metrics. # Top level method to register all the prometheus metrics.
def setup_prometheus_metrics def setup_prometheus_metrics(torun)
@p_metrics = vmpooler_metrics_table @p_metrics = vmpooler_metrics_table
@p_metrics.each do |_name, metric_spec| @p_metrics.each do |_name, metric_spec|
# Only register metrics appropriate to api or manager
next if (torun & metric_spec[:torun]).empty?
if metric_spec.key? :metric_suffixes if metric_spec.key? :metric_suffixes
# Iterate thru the suffixes if provided to register multiple counters here. # Iterate thru the suffixes if provided to register multiple counters here.
metric_spec[:metric_suffixes].each do |metric_suffix| metric_spec[:metric_suffixes].each do |metric_suffix|

View file

@ -40,7 +40,7 @@ describe Vmpooler::API::V1 do
before(:each) do before(:each) do
expect(app).to receive(:run!).once expect(app).to receive(:run!).once
app.execute(['api'], config, redis, metrics) app.execute([:api], config, redis, metrics)
app.settings.set :config, auth: false app.settings.set :config, auth: false
create_token('abcdefghijklmnopqrstuvwxyz012345', 'jdoe', current_time) create_token('abcdefghijklmnopqrstuvwxyz012345', 'jdoe', current_time)
end end

View file

@ -43,7 +43,7 @@ describe Vmpooler::API::V1 do
before(:each) do before(:each) do
expect(app).to receive(:run!).once expect(app).to receive(:run!).once
app.execute(['api'], config, redis, metrics) app.execute([:api], config, redis, metrics)
app.settings.set :config, auth: false app.settings.set :config, auth: false
app.settings.set :checkoutlock, checkoutlock app.settings.set :checkoutlock, checkoutlock
create_token('abcdefghijklmnopqrstuvwxyz012345', 'jdoe', current_time) create_token('abcdefghijklmnopqrstuvwxyz012345', 'jdoe', current_time)

View file

@ -37,7 +37,7 @@ describe Vmpooler::API::V1 do
before(:each) do before(:each) do
expect(app).to receive(:run!).once expect(app).to receive(:run!).once
app.execute(['api'], config, redis, metrics) app.execute([:api], config, redis, metrics)
app.settings.set :config, auth: false app.settings.set :config, auth: false
create_token('abcdefghijklmnopqrstuvwxyz012345', 'jdoe', current_time) create_token('abcdefghijklmnopqrstuvwxyz012345', 'jdoe', current_time)
end end

View file

@ -40,7 +40,7 @@ describe Vmpooler::API::V1 do
before(:each) do before(:each) do
expect(app).to receive(:run!).once expect(app).to receive(:run!).once
app.execute(['api'], config, redis, nil) app.execute([:api], config, redis, nil)
app.settings.set :config, auth: false app.settings.set :config, auth: false
create_token('abcdefghijklmnopqrstuvwxyz012345', 'jdoe', current_time) create_token('abcdefghijklmnopqrstuvwxyz012345', 'jdoe', current_time)
end end

View file

@ -22,7 +22,7 @@ describe Vmpooler::API::V1 do
before(:each) do before(:each) do
expect(app).to receive(:run!).once expect(app).to receive(:run!).once
app.execute(['api'], config, redis, nil) app.execute([:api], config, redis, nil)
end end
describe 'GET /token' do describe 'GET /token' do
@ -106,7 +106,7 @@ describe Vmpooler::API::V1 do
before(:each) do before(:each) do
expect(app).to receive(:run!).once expect(app).to receive(:run!).once
app.execute(['api'], config, redis, nil) app.execute([:api], config, redis, nil)
app.settings.set :config, config app.settings.set :config, config
app.settings.set :redis, redis app.settings.set :redis, redis
end end

View file

@ -43,7 +43,7 @@ describe Vmpooler::API::V1 do
before(:each) do before(:each) do
expect(app).to receive(:run!).once expect(app).to receive(:run!).once
app.execute(['api'], config, redis, metrics) app.execute([:api], config, redis, metrics)
create_token('abcdefghijklmnopqrstuvwxyz012345', 'jdoe', current_time) create_token('abcdefghijklmnopqrstuvwxyz012345', 'jdoe', current_time)
end end

View file

@ -40,7 +40,7 @@ describe Vmpooler::API::V1 do
before(:each) do before(:each) do
expect(app).to receive(:run!).once expect(app).to receive(:run!).once
app.execute(['api'], config, redis, metrics) app.execute([:api], config, redis, metrics)
app.settings.set :config, auth: false app.settings.set :config, auth: false
app.settings.set :checkoutlock, checkoutlock app.settings.set :checkoutlock, checkoutlock
create_token('abcdefghijklmnopqrstuvwxyz012345', 'jdoe', current_time) create_token('abcdefghijklmnopqrstuvwxyz012345', 'jdoe', current_time)

View file

@ -41,7 +41,7 @@ describe Vmpooler::API::V1 do
before(:each) do before(:each) do
expect(app).to receive(:run!).once expect(app).to receive(:run!).once
app.execute(['api'], config, redis, metrics) app.execute([:api], config, redis, metrics)
app.settings.set :config, auth: false app.settings.set :config, auth: false
app.settings.set :checkoutlock, checkoutlock app.settings.set :checkoutlock, checkoutlock
create_token('abcdefghijklmnopqrstuvwxyz012345', 'jdoe', current_time) create_token('abcdefghijklmnopqrstuvwxyz012345', 'jdoe', current_time)

View file

@ -26,7 +26,7 @@ describe Vmpooler::API do
before(:each) do before(:each) do
expect(app).to receive(:run!) expect(app).to receive(:run!)
app.execute(['api'], config, redis, nil) app.execute([:api], config, redis, nil)
app.settings.set :config, auth: false app.settings.set :config, auth: false
end end

View file

@ -55,7 +55,7 @@ describe 'prometheus' do
context 'setup_prometheus_metrics' do context 'setup_prometheus_metrics' do
before(:all) do before(:all) do
Prometheus::Client.config.data_store = Prometheus::Client::DataStores::Synchronized.new Prometheus::Client.config.data_store = Prometheus::Client::DataStores::Synchronized.new
subject.setup_prometheus_metrics subject.setup_prometheus_metrics(%i[api manager])
end end
let(:MCOUNTER) { 1 } let(:MCOUNTER) { 1 }
@ -63,7 +63,7 @@ describe 'prometheus' do
it 'calls add_prometheus_metric for each item in list' do it 'calls add_prometheus_metric for each item in list' do
Prometheus::Client.config.data_store = Prometheus::Client::DataStores::Synchronized.new Prometheus::Client.config.data_store = Prometheus::Client::DataStores::Synchronized.new
expect(subject).to receive(:add_prometheus_metric).at_least(subject.vmpooler_metrics_table.size).times expect(subject).to receive(:add_prometheus_metric).at_least(subject.vmpooler_metrics_table.size).times
subject.setup_prometheus_metrics subject.setup_prometheus_metrics(%i[api manager])
end end
end end
@ -102,6 +102,48 @@ describe 'prometheus' do
po.get(labels: metric[:labels]) po.get(labels: metric[:labels])
}.by(1) }.by(1)
end end
it 'Increments delete.failed' do
bad_template = 'test-template'
expect { subject.increment('delete.failed') }.to change {
metric, po = subject.get('delete.failed')
po.get(labels: metric[:labels])
}.by(1)
end
it 'Increments delete.success' do
bad_template = 'test-template'
expect { subject.increment('delete.success') }.to change {
metric, po = subject.get('delete.success')
po.get(labels: metric[:labels])
}.by(1)
end
it 'Increments ondemandrequest_generate.duplicaterequests' do
bad_template = 'test-template'
expect { subject.increment('ondemandrequest_generate.duplicaterequests') }.to change {
metric, po = subject.get('ondemandrequest_generate.duplicaterequests')
po.get(labels: metric[:labels])
}.by(1)
end
it 'Increments ondemandrequest_generate.success' do
bad_template = 'test-template'
expect { subject.increment('ondemandrequest_generate.success') }.to change {
metric, po = subject.get('ondemandrequest_generate.success')
po.get(labels: metric[:labels])
}.by(1)
end
it 'Increments ondemandrequest_fail.toomanyrequests.#{bad_template}' do
bad_template = 'test-template'
expect { subject.increment("ondemandrequest_fail.toomanyrequests.#{bad_template}") }.to change {
metric, po = subject.get("ondemandrequest_fail.toomanyrequests.#{bad_template}")
po.get(labels: metric[:labels])
}.by(1)
end
it 'Increments ondemandrequest_fail.invalid.#{bad_template}' do
bad_template = 'test-template'
expect { subject.increment("ondemandrequest_fail.invalid.#{bad_template}") }.to change {
metric, po = subject.get("ondemandrequest_fail.invalid.#{bad_template}")
po.get(labels: metric[:labels])
}.by(1)
end
it 'Increments config.invalid.#{bad_template}' do it 'Increments config.invalid.#{bad_template}' do
bad_template = 'test-template' bad_template = 'test-template'
expect { subject.increment("config.invalid.#{bad_template}") }.to change { expect { subject.increment("config.invalid.#{bad_template}") }.to change {