From 9de3fd60a012c69070a3371efec9c9fd54d9071a Mon Sep 17 00:00:00 2001 From: David Roetzel Date: Tue, 29 Oct 2024 11:10:17 +0100 Subject: [PATCH] Add telemetry for status / bio formatting (#32677) --- app/helpers/formatting_helper.rb | 18 ++++++- app/lib/text_formatter.rb | 87 ++++++++++++++++++-------------- 2 files changed, 66 insertions(+), 39 deletions(-) diff --git a/app/helpers/formatting_helper.rb b/app/helpers/formatting_helper.rb index 2ef7d362d8..9d5a2e2478 100644 --- a/app/helpers/formatting_helper.rb +++ b/app/helpers/formatting_helper.rb @@ -27,7 +27,14 @@ module FormattingHelper module_function :extract_status_plain_text def status_content_format(status) - html_aware_format(status.text, status.local?, preloaded_accounts: [status.account] + (status.respond_to?(:active_mentions) ? status.active_mentions.map(&:account) : [])) + MastodonOTELTracer.in_span('HtmlAwareFormatter rendering') do |span| + span.add_attributes( + 'app.formatter.content.type' => 'status', + 'app.formatter.content.origin' => status.local? ? 'local' : 'remote' + ) + + html_aware_format(status.text, status.local?, preloaded_accounts: [status.account] + (status.respond_to?(:active_mentions) ? status.active_mentions.map(&:account) : [])) + end end def rss_status_content_format(status) @@ -39,7 +46,14 @@ module FormattingHelper end def account_bio_format(account) - html_aware_format(account.note, account.local?) + MastodonOTELTracer.in_span('HtmlAwareFormatter rendering') do |span| + span.add_attributes( + 'app.formatter.content.type' => 'account_bio', + 'app.formatter.content.origin' => account.local? ? 'local' : 'remote' + ) + + html_aware_format(account.note, account.local?) + end end def account_field_value_format(field, with_rel_me: true) diff --git a/app/lib/text_formatter.rb b/app/lib/text_formatter.rb index 2b3febc219..5e8e73a217 100644 --- a/app/lib/text_formatter.rb +++ b/app/lib/text_formatter.rb @@ -33,17 +33,24 @@ class TextFormatter def to_s return ''.html_safe if text.blank? - html = rewrite do |entity| - if entity[:url] - link_to_url(entity) - elsif entity[:hashtag] - link_to_hashtag(entity) - elsif entity[:screen_name] - link_to_mention(entity) + html = nil + MastodonOTELTracer.in_span('TextFormatter#to_s extract_and_rewrite') do + html = rewrite do |entity| + if entity[:url] + link_to_url(entity) + elsif entity[:hashtag] + link_to_hashtag(entity) + elsif entity[:screen_name] + link_to_mention(entity) + end end end - html = simple_format(html, {}, sanitize: false).delete("\n") if multiline? + if multiline? + MastodonOTELTracer.in_span('TextFormatter#to_s simple_format') do + html = simple_format(html, {}, sanitize: false).delete("\n") + end + end html.html_safe # rubocop:disable Rails/OutputSafety end @@ -93,48 +100,54 @@ class TextFormatter end def link_to_url(entity) - TextFormatter.shortened_link(entity[:url], rel_me: with_rel_me?) + MastodonOTELTracer.in_span('TextFormatter#link_to_url') do + TextFormatter.shortened_link(entity[:url], rel_me: with_rel_me?) + end end def link_to_hashtag(entity) - hashtag = entity[:hashtag] - url = tag_url(hashtag) + MastodonOTELTracer.in_span('TextFormatter#link_to_hashtag') do + hashtag = entity[:hashtag] + url = tag_url(hashtag) - <<~HTML.squish - - HTML + <<~HTML.squish + + HTML + end end def link_to_mention(entity) - username, domain = entity[:screen_name].split('@') - domain = nil if local_domain?(domain) - account = nil + MastodonOTELTracer.in_span('TextFormatter#link_to_mention') do + username, domain = entity[:screen_name].split('@') + domain = nil if local_domain?(domain) + account = nil - if preloaded_accounts? - same_username_hits = 0 + if preloaded_accounts? + same_username_hits = 0 - preloaded_accounts.each do |other_account| - same_username = other_account.username.casecmp(username).zero? - same_domain = other_account.domain.nil? ? domain.nil? : other_account.domain.casecmp(domain)&.zero? + preloaded_accounts.each do |other_account| + same_username = other_account.username.casecmp(username).zero? + same_domain = other_account.domain.nil? ? domain.nil? : other_account.domain.casecmp(domain)&.zero? - if same_username && !same_domain - same_username_hits += 1 - elsif same_username && same_domain - account = other_account + if same_username && !same_domain + same_username_hits += 1 + elsif same_username && same_domain + account = other_account + end end + else + account = entity_cache.mention(username, domain) end - else - account = entity_cache.mention(username, domain) + + return "@#{h(entity[:screen_name])}" if account.nil? + + url = ActivityPub::TagManager.instance.url_for(account) + display_username = same_username_hits&.positive? || with_domains? ? account.pretty_acct : account.username + + <<~HTML.squish + @#{h(display_username)} + HTML end - - return "@#{h(entity[:screen_name])}" if account.nil? - - url = ActivityPub::TagManager.instance.url_for(account) - display_username = same_username_hits&.positive? || with_domains? ? account.pretty_acct : account.username - - <<~HTML.squish - @#{h(display_username)} - HTML end def entity_cache