Skip to content

Commit

Permalink
FEATURE: Export metric for highest sequence usage
Browse files Browse the repository at this point in the history
Plugin already exports `postgres_highest_sequence`, but the value cannot
be reliable used for alerts because it is not linked with the maximum
value of the column that uses it.

In other words, a sequence may be used with an `integer` or a `bigint`
column, which have very different maximum values. The highest
`last_value` reported may be cause of concern for an `integer` column
because it is close to the limit, but not a problem for a `bigint`
column.
  • Loading branch information
nbianca committed Jun 24, 2024
1 parent b1b899c commit 5b6bcda
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 1 deletion.
5 changes: 5 additions & 0 deletions lib/collector.rb
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,11 @@ def ensure_global_metrics
"The highest last_value from the pg_sequences table",
)

global_metrics << Gauge.new(
"postgres_highest_sequence_usage",
"The highest usage of the sequences. Usage is calculated as the ratio between last_value from the pg_sequences table and the determined maximum value for the column using the sequence",
)

@global_metrics = global_metrics
end

Expand Down
48 changes: 47 additions & 1 deletion lib/internal_metric/global.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ class Global < Base
:missing_s3_uploads,
:version_info,
:readonly_sites,
:postgres_highest_sequence
:postgres_highest_sequence,
:postgres_highest_sequence_usage

def initialize
@active_app_reqs = 0
Expand Down Expand Up @@ -168,13 +169,17 @@ def collect
@readonly_sites = collect_readonly_sites

@postgres_highest_sequence = calc_postgres_highest_sequence

@postgres_highest_sequence_usage = calc_postgres_highest_sequence_usage
end

# For testing purposes
def reset!
@@missing_uploads = nil
@@postgres_highest_sequence_last_check = nil
@@postgres_highest_sequence_cache = nil
@@postgres_highest_sequence_usage_last_check = nil
@@postgres_highest_sequence_usage_cache = nil
end

private
Expand Down Expand Up @@ -381,5 +386,46 @@ def calc_postgres_highest_sequence
Discourse.warn_exception(e, message: "Failed to collect postgres_highest_sequence value")
end
end

def calc_postgres_highest_sequence_usage
@@postgres_highest_sequence_usage_last_check ||= 0

if @@postgres_highest_sequence_usage_last_check >=
Time.now.to_i - PG_HIGHEST_SEQUENCE_CHECK_SECONDS
return @@postgres_highest_sequence_usage_cache
end

@@postgres_highest_sequence_usage_last_check = Time.now.to_i

result = {}

RailsMultisite::ConnectionManagement.each_connection do |db|
result[{ db: db }] = DB.query_single(<<~SQL)[0]
WITH sequences AS (
SELECT table_name,
column_name,
information_schema.columns.data_type,
COALESCE(last_value, 0) last_value,
CASE information_schema.columns.data_type
WHEN 'integer' THEN POWER(2, 31)
WHEN 'bigint' THEN POWER(2, 63)
ELSE NULL
END max_value
FROM information_schema.columns
JOIN pg_sequences ON sequencename = REPLACE(REPLACE(column_default, 'nextval(''', ''), '''::regclass)', '')
)
SELECT MAX(last_value / max_value) FROM sequences
SQL
end

@@postgres_highest_sequence_usage_cache = result
rescue => e
if @postgres_master_available == 1
Discourse.warn_exception(
e,
message: "Failed to collect postgres_highest_sequence_usage value",
)
end
end
end
end
4 changes: 4 additions & 0 deletions spec/lib/internal_metric/global_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,12 @@ module DiscoursePrometheus::InternalMetric
expect(metric.postgres_highest_sequence).to be_a_kind_of(Hash)
expect(metric.postgres_highest_sequence[{ db: "default" }]).to be_present

expect(metric.postgres_highest_sequence_usage).to be_a_kind_of(Hash)
expect(metric.postgres_highest_sequence_usage[{ db: "default" }]).to be_present

expect do metric.collect end.not_to change {
metric.class.class_variable_get(:@@postgres_highest_sequence_last_check)
metric.class.class_variable_get(:@@postgres_highest_sequence_usage_last_check)
}
end
end
Expand Down

0 comments on commit 5b6bcda

Please sign in to comment.