Skip to content

Commit

Permalink
Merge pull request #2269 from alphagov/custom-prometheus-metrics
Browse files Browse the repository at this point in the history
Push fact check metrics to prometheus
  • Loading branch information
Tetrino authored Sep 13, 2024
2 parents 00b906f + f40059d commit 7c3f0ce
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 18 deletions.
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ gem "mousetrap-rails"
gem "nested_form", git: "https://github.com/alphagov/nested_form.git", branch: "add-wrapper-class"
gem "null_logger"
gem "plek"
gem "prometheus-client"
gem "rails_autolink"
gem "rest-client", require: false
gem "select2-rails", "~> 3.5.9" # Updating this will mean updating the styling as 4 & > have a new approach to class names.
Expand Down
3 changes: 3 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,8 @@ GEM
ast (~> 2.4.1)
racc
plek (5.2.0)
prometheus-client (4.2.3)
base64
prometheus_exporter (2.1.1)
webrick
pry (0.14.1)
Expand Down Expand Up @@ -872,6 +874,7 @@ DEPENDENCIES
nested_form!
null_logger
plek
prometheus-client
pry-byebug
rack
rails (= 7.0.8.3)
Expand Down
5 changes: 3 additions & 2 deletions app/lib/fact_check_email_handler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
class FactCheckEmailHandler
attr_accessor :fact_check_config

def initialize(fact_check_config)
def initialize(fact_check_config, unprocessed_emails_gauge)
@fact_check_config = fact_check_config
@unprocessed_emails_gauge = unprocessed_emails_gauge
end

def process_message(message)
Expand All @@ -35,7 +36,7 @@ def process
unprocessed_emails_count += 1
end

GovukStatsd.gauge("unprocessed_emails.count", unprocessed_emails_count)
@unprocessed_emails_gauge.set(unprocessed_emails_count)
rescue StandardError => e
# Occasionally, there is an error when connecting to the mailbox in production.
# It seems a very transient error, and since the job is run every few minutes isn't really a problem, but if the
Expand Down
11 changes: 10 additions & 1 deletion script/mail_fetcher
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,12 @@ end

Rails.logger.info "Running MailFetcher in #{Rails.env} mode - #{Time.zone.now.utc}"

handler = FactCheckEmailHandler.new(Publisher::Application.fact_check_config)
registry = Prometheus::Client.registry
gauge = registry.gauge(
:publisher_fact_check_unprocessed_emails_total,
docstring: "Number of unprocessed fact check emails",
)
handler = FactCheckEmailHandler.new(Publisher::Application.fact_check_config, gauge)

# The lock is created and belongs to this process for as long as the `life`.
# When the block has finished executing, the lock is explicitly released.
Expand Down Expand Up @@ -50,3 +55,7 @@ rescue StandardError => e
end

Rails.logger.info "Finished running MailFetcher in #{Rails.env} mode - #{Time.zone.now.utc}"
Prometheus::Client::Push.new(
job: "publisher-metrics",
gateway: ENV.fetch("PROMETHEUS_PUSHGATEWAY_URL"),
).add(registry)
20 changes: 10 additions & 10 deletions test/integration/fact_check_email_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def assert_correct_state(key, value, state)
message[key] = value

Mail.stubs(:all).yields(message)
FactCheckEmailHandler.new(fact_check_config).process
FactCheckEmailHandler.new(fact_check_config, stub.stubs(:set)).process

answer.reload
assert answer.public_send("#{state}?")
Expand All @@ -41,7 +41,7 @@ def assert_correct_state(key, value, state)

answer.destroy!

handler = FactCheckEmailHandler.new(fact_check_config)
handler = FactCheckEmailHandler.new(fact_check_config, stub.stubs(:set))
handler.process

assert message.is_marked_for_delete?
Expand All @@ -53,7 +53,7 @@ def assert_correct_state(key, value, state)
message = fact_check_mail_for(answer)
Mail.stubs(:all).yields(message)

handler = FactCheckEmailHandler.new(fact_check_config)
handler = FactCheckEmailHandler.new(fact_check_config, stub.stubs(:set))
handler.process

answer.reload
Expand All @@ -71,7 +71,7 @@ def assert_correct_state(key, value, state)

Mail.stubs(:all).yields(fact_check_mail_for(answer))

handler = FactCheckEmailHandler.new(fact_check_config)
handler = FactCheckEmailHandler.new(fact_check_config, stub.stubs(:set))
handler.process

answer.reload
Expand All @@ -96,7 +96,7 @@ def assert_correct_state(key, value, state)
fact_check_mail_for(answer1, body: "Third Message"),
)

handler = FactCheckEmailHandler.new(fact_check_config)
handler = FactCheckEmailHandler.new(fact_check_config, stub.stubs(:set))
handler.process

answer1.reload
Expand All @@ -122,7 +122,7 @@ def assert_correct_state(key, value, state)

Mail.stubs(:all).yields(message)

handler = FactCheckEmailHandler.new(fact_check_config)
handler = FactCheckEmailHandler.new(fact_check_config, stub.stubs(:set))
handler.process

assert_not message.is_marked_for_delete?
Expand All @@ -139,7 +139,7 @@ def assert_correct_state(key, value, state)

Mail.stubs(:all).multiple_yields(message_cc, message_bcc)

handler = FactCheckEmailHandler.new(fact_check_config)
handler = FactCheckEmailHandler.new(fact_check_config, stub.stubs(:set))
handler.process

assert message_cc.is_marked_for_delete?
Expand All @@ -152,7 +152,7 @@ def assert_correct_state(key, value, state)

Mail.stubs(:all).yields(message)

handler = FactCheckEmailHandler.new(fact_check_config)
handler = FactCheckEmailHandler.new(fact_check_config, stub.stubs(:set))
handler.process_message(message)
assert message.is_marked_for_delete?
end
Expand All @@ -163,7 +163,7 @@ def assert_correct_state(key, value, state)

Mail.stubs(:all).yields(message)

handler = FactCheckEmailHandler.new(fact_check_config)
handler = FactCheckEmailHandler.new(fact_check_config, stub.stubs(:set))

handler.process_message(message)
assert message.is_marked_for_delete?
Expand All @@ -182,7 +182,7 @@ def assert_correct_state(key, value, state)
fact_check_mail_for(answer2, body: "Second Message"),
)

handler = FactCheckEmailHandler.new(fact_check_config)
handler = FactCheckEmailHandler.new(fact_check_config, stub.stubs(:set))

invocations = 0
handler.process do
Expand Down
15 changes: 10 additions & 5 deletions test/unit/lib/fact_check_email_handler_test.rb
Original file line number Diff line number Diff line change
@@ -1,29 +1,34 @@
require "test_helper"

class FactCheckEmailHandlerTest < ActiveSupport::TestCase
setup do
@gauge = stub
end

def handler
FactCheckEmailHandler.new(Publisher::Application.fact_check_config)
FactCheckEmailHandler.new(Publisher::Application.fact_check_config, @gauge)
end

test "#process ignores 'out of office' emails" do
out_of_office_message = Mail.new { subject("Automatic reply: out of office") }
Mail.stubs(:all).yields(out_of_office_message)
@gauge.expects(:set).with(0)
handler.process
assert out_of_office_message.is_marked_for_delete?
end

test "#process sends count of unprocessed emails to Graphite" do
test "#process sends count of unprocessed emails to Prometheus" do
processed_message = Mail.new { subject("Automatic reply: out of office") }
unprocessed_message = Mail.new { subject("Any other subject") }
GovukStatsd.expects(:gauge).with("unprocessed_emails.count", 1)
@gauge.expects(:set).with(1)
Mail.stubs(:all).multiple_yields(processed_message, unprocessed_message)

handler.process
end

test "#process does not send count of unprocessed emails to Graphite when emails cannot be retrieved" do
test "#process does not send count of unprocessed emails to Prometheus when emails cannot be retrieved" do
Mail.stubs(:all).raises(StandardError)
GovukStatsd.expects(:gauge).never
@gauge.expects(:set).never

handler.process
end
Expand Down

0 comments on commit 7c3f0ce

Please sign in to comment.