Commit 0bf0b895 authored by Piotr Skorupa's avatar Piotr Skorupa Committed by Mayra Cabrera

Add estimate_batch_distinct_count operation block passing support

parent 5dbc1c26
...@@ -110,14 +110,14 @@ end ...@@ -110,14 +110,14 @@ end
There is support for: There is support for:
- `count`, `distinct_count` for [database metrics](#database-metrics). - `count`, `distinct_count`, `estimate_batch_distinct_count` for [database metrics](#database-metrics).
- [Redis metrics](#redis-metrics). - [Redis metrics](#redis-metrics).
- [Redis HLL metrics](#redis-hyperloglog-metrics). - [Redis HLL metrics](#redis-hyperloglog-metrics).
- [Generic metrics](#generic-metrics), which are metrics based on settings or configurations. - [Generic metrics](#generic-metrics), which are metrics based on settings or configurations.
Currently, there is no support for: Currently, there is no support for:
- `add`, `sum`, `histogram`, `estimate_batch_distinct_count` for database metrics. - `add`, `sum`, `histogram` for database metrics.
You can [track the progress to support these](https://gitlab.com/groups/gitlab-org/-/epics/6118). You can [track the progress to support these](https://gitlab.com/groups/gitlab-org/-/epics/6118).
...@@ -128,7 +128,7 @@ To create a stub instrumentation for a Service Ping metric, you can use a dedica ...@@ -128,7 +128,7 @@ To create a stub instrumentation for a Service Ping metric, you can use a dedica
The generator takes the class name as an argument and the following options: The generator takes the class name as an argument and the following options:
- `--type=TYPE` Required. Indicates the metric type. It must be one of: `database`, `generic`, `redis`. - `--type=TYPE` Required. Indicates the metric type. It must be one of: `database`, `generic`, `redis`.
- `--operation` Required for `database` type. It must be one of: `count`, `distinct_count`. - `--operation` Required for `database` type. It must be one of: `count`, `distinct_count`, `estimate_batch_distinct_count`.
- `--ee` Indicates if the metric is for EE. - `--ee` Indicates if the metric is for EE.
```shell ```shell
......
...@@ -15,7 +15,7 @@ module Gitlab ...@@ -15,7 +15,7 @@ module Gitlab
redis: 'Redis' redis: 'Redis'
}.freeze }.freeze
ALLOWED_OPERATIONS = %w(count distinct_count).freeze ALLOWED_OPERATIONS = %w(count distinct_count estimate_batch_distinct_count).freeze
source_root File.expand_path('usage_metric/templates', __dir__) source_root File.expand_path('usage_metric/templates', __dir__)
......
...@@ -33,16 +33,17 @@ module Gitlab ...@@ -33,16 +33,17 @@ module Gitlab
@metric_relation = block @metric_relation = block
end end
def operation(symbol, column: nil) def operation(symbol, column: nil, &block)
@metric_operation = symbol @metric_operation = symbol
@column = column @column = column
@metric_operation_block = block if block_given?
end end
def cache_start_and_finish_as(cache_key) def cache_start_and_finish_as(cache_key)
@cache_key = cache_key @cache_key = cache_key
end end
attr_reader :metric_operation, :metric_relation, :metric_start, :metric_finish, :column, :cache_key attr_reader :metric_operation, :metric_relation, :metric_start, :metric_finish, :metric_operation_block, :column, :cache_key
end end
def value def value
...@@ -52,7 +53,8 @@ module Gitlab ...@@ -52,7 +53,8 @@ module Gitlab
.call(relation, .call(relation,
self.class.column, self.class.column,
start: start, start: start,
finish: finish) finish: finish,
&self.class.metric_operation_block)
end end
def to_sql def to_sql
......
...@@ -4,11 +4,11 @@ require 'spec_helper' ...@@ -4,11 +4,11 @@ require 'spec_helper'
RSpec.describe Gitlab::Usage::Metrics::Instrumentations::DatabaseMetric do RSpec.describe Gitlab::Usage::Metrics::Instrumentations::DatabaseMetric do
subject do subject do
described_class.tap do |m| described_class.tap do |metric_class|
m.relation { Issue } metric_class.relation { Issue }
m.operation :count metric_class.operation :count
m.start { m.relation.minimum(:id) } metric_class.start { metric_class.relation.minimum(:id) }
m.finish { m.relation.maximum(:id) } metric_class.finish { metric_class.relation.maximum(:id) }
end.new(time_frame: 'all') end.new(time_frame: 'all')
end end
...@@ -38,9 +38,9 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::DatabaseMetric do ...@@ -38,9 +38,9 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::DatabaseMetric do
context 'with start and finish not called' do context 'with start and finish not called' do
subject do subject do
described_class.tap do |m| described_class.tap do |metric_class|
m.relation { Issue } metric_class.relation { Issue }
m.operation :count metric_class.operation :count
end.new(time_frame: 'all') end.new(time_frame: 'all')
end end
...@@ -51,12 +51,12 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::DatabaseMetric do ...@@ -51,12 +51,12 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::DatabaseMetric do
context 'with cache_start_and_finish_as called' do context 'with cache_start_and_finish_as called' do
subject do subject do
described_class.tap do |m| described_class.tap do |metric_class|
m.relation { Issue } metric_class.relation { Issue }
m.operation :count metric_class.operation :count
m.start { m.relation.minimum(:id) } metric_class.start { metric_class.relation.minimum(:id) }
m.finish { m.relation.maximum(:id) } metric_class.finish { metric_class.relation.maximum(:id) }
m.cache_start_and_finish_as :special_issue_count metric_class.cache_start_and_finish_as :special_issue_count
end.new(time_frame: 'all') end.new(time_frame: 'all')
end end
...@@ -71,5 +71,45 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::DatabaseMetric do ...@@ -71,5 +71,45 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::DatabaseMetric do
expect(Rails.cache.read('metric_instrumentation/special_issue_count_maximum_id')).to eq(issues.max_by(&:id).id) expect(Rails.cache.read('metric_instrumentation/special_issue_count_maximum_id')).to eq(issues.max_by(&:id).id)
end end
end end
context 'with estimate_batch_distinct_count' do
subject do
described_class.tap do |metric_class|
metric_class.relation { Issue }
metric_class.operation(:estimate_batch_distinct_count)
metric_class.start { metric_class.relation.minimum(:id) }
metric_class.finish { metric_class.relation.maximum(:id) }
end.new(time_frame: 'all')
end
it 'calculates a correct result' do
expect(subject.value).to be_within(Gitlab::Database::PostgresHll::BatchDistinctCounter::ERROR_RATE).percent_of(3)
end
context 'with block passed to operation' do
let(:buckets) { double('Buckets').as_null_object }
subject do
described_class.tap do |metric_class|
metric_class.relation { Issue }
metric_class.operation(:estimate_batch_distinct_count) do |result|
result.foo
end
metric_class.start { metric_class.relation.minimum(:id) }
metric_class.finish { metric_class.relation.maximum(:id) }
end.new(time_frame: 'all')
end
before do
allow(Gitlab::Database::PostgresHll::Buckets).to receive(:new).and_return(buckets)
end
it 'calls the block passing HLL buckets as an argument' do
expect(buckets).to receive(:foo)
subject.value
end
end
end
end 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