From 5a0a46887c2cf1a1afb9bec50249ba0a0ed2da55 Mon Sep 17 00:00:00 2001 From: Jamie Gaskins Date: Mon, 29 Mar 2021 09:33:32 -0400 Subject: [PATCH] Instrument EmailDigestArticleCollector (#13153) * Instrument EmailDigestArticleCollector On DEV, since we skip this with sidekiq-cron and instead process them inline using Heroku Scheduler (which is not instrumented), we miss out on all instrumentation for this process and have no idea how long it takes to process each user. With this instrumentation in place, we can see how long it takes to process each user and aggregate them to see how long it takes to process all users. This commit also adds an Instrumentation mixin that we can use to instrument blocks easily: instrument "MyClass.my_method", tags: { article: article.id } do |span| # ... end * Add Instrumentation mixin Oops, completely forgot to commit this file --- .../email_digest_article_collector.rb | 69 +++++++++++-------- app/services/instrumentation.rb | 7 ++ 2 files changed, 47 insertions(+), 29 deletions(-) create mode 100644 app/services/instrumentation.rb diff --git a/app/services/email_digest_article_collector.rb b/app/services/email_digest_article_collector.rb index d86d2e536..b7173caf7 100644 --- a/app/services/email_digest_article_collector.rb +++ b/app/services/email_digest_article_collector.rb @@ -1,39 +1,47 @@ class EmailDigestArticleCollector + include Instrumentation + + ARTICLES_TO_SEND = "EmailDigestArticleCollector#articles_to_send".freeze + def initialize(user) @user = user end def articles_to_send - return [] unless should_receive_email? + # rubocop:disable Metrics/BlockLength + instrument ARTICLES_TO_SEND, tags: %W[user_id:#{@user.id}] do + return [] unless should_receive_email? - articles = if user_has_followings? - experience_level_rating = (@user.experience_level || 5) - experience_level_rating_min = experience_level_rating - 3.6 - experience_level_rating_max = experience_level_rating + 3.6 + articles = if user_has_followings? + experience_level_rating = (@user.experience_level || 5) + experience_level_rating_min = experience_level_rating - 3.6 + experience_level_rating_max = experience_level_rating + 3.6 - @user.followed_articles - .select(:title, :description, :path) - .published - .where("published_at > ?", cutoff_date) - .where(email_digest_eligible: true) - .where.not(user_id: @user.id) - .where("score > ?", 12) - .where("experience_level_rating > ? AND experience_level_rating < ?", - experience_level_rating_min, experience_level_rating_max) - .order(score: :desc) - .limit(6) - else - Article.select(:title, :description, :path) - .published - .where("published_at > ?", cutoff_date) - .where(featured: true, email_digest_eligible: true) - .where.not(user_id: @user.id) - .where("score > ?", 25) - .order(score: :desc) - .limit(6) - end + @user.followed_articles + .select(:title, :description, :path) + .published + .where("published_at > ?", cutoff_date) + .where(email_digest_eligible: true) + .where.not(user_id: @user.id) + .where("score > ?", 12) + .where("experience_level_rating > ? AND experience_level_rating < ?", + experience_level_rating_min, experience_level_rating_max) + .order(score: :desc) + .limit(6) + else + Article.select(:title, :description, :path) + .published + .where("published_at > ?", cutoff_date) + .where(featured: true, email_digest_eligible: true) + .where.not(user_id: @user.id) + .where("score > ?", 25) + .order(score: :desc) + .limit(6) + end - articles.length < 3 ? [] : articles + articles.length < 3 ? [] : articles + end + # rubocop:enable Metrics/BlockLength end private @@ -81,7 +89,10 @@ class EmailDigestArticleCollector end def last_user_emails - @last_user_emails ||= @user.email_messages.select(:sent_at, - :opened_at).where(mailer: "DigestMailer#digest_email").limit(10) + @last_user_emails ||= @user + .email_messages + .select(:sent_at, :opened_at) + .where(mailer: "DigestMailer#digest_email") + .limit(10) end end diff --git a/app/services/instrumentation.rb b/app/services/instrumentation.rb new file mode 100644 index 000000000..47f1eb3e7 --- /dev/null +++ b/app/services/instrumentation.rb @@ -0,0 +1,7 @@ +module Instrumentation + def instrument(operation, tags: [], &block) + # TODO: (@jgaskins): Extract the knowledge of which tracing library + # we're using, like we did with ForemStatsDriver + Datadog.tracer.trace operation, tags: tags, &block + end +end