Skip to content

[analytics] Add browser request accept-language#4060

Merged
imnasnainaec merged 2 commits intomasterfrom
otel-accept-lang
Dec 15, 2025
Merged

[analytics] Add browser request accept-language#4060
imnasnainaec merged 2 commits intomasterfrom
otel-accept-lang

Conversation

@imnasnainaec
Copy link
Collaborator

@imnasnainaec imnasnainaec commented Dec 11, 2025

Enables browser language analytics, non-PII analytics requested by SIL leadership.


This change is Reviewable

Summary by CodeRabbit

  • New Features

    • Recognizes and tags the Accept-Language header in HTTP requests.
  • Refactor

    • Simplified and optimized query string handling for cleaner, more reliable URL tagging.

✏️ Tip: You can customize this high-level summary in your review settings.

@imnasnainaec imnasnainaec self-assigned this Dec 11, 2025
@imnasnainaec imnasnainaec added the 🟨Medium Medium-priority PR label Dec 11, 2025
@coderabbitai
Copy link

coderabbitai bot commented Dec 11, 2025

Walkthrough

Modified Backend/Otel/OtelKernel.cs to tag Accept-Language headers as http.request.header.accept_language for AspNetCore requests and to simplify HttpClient query tagging using a single null-safe query check.

Changes

Cohort / File(s) Summary
HTTP request telemetry enrichment
Backend/Otel/OtelKernel.cs
Added tagging of the Accept-Language header as http.request.header.accept_language for AspNetCore. Simplified HttpClient query-tagging by replacing nested null checks with a single null-safe check that sets url.query when a query exists.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

  • Single-file change with small, local logic additions and simplifications
  • Areas to check:
    • Correct header name and casing for tagging (http.request.header.accept_language)
    • Null-safe query check covers all HttpClient URI edge cases (empty vs null query)

Poem

🐰 I sniffed the headers, found a tongue to name,

I tucked the query tidy, no nested checks to blame,
Telemetry twinkles, small changes, bright and neat,
One file hopped forward on quick, clever feet,
nibble-nudge celebration in every beat.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly describes the main change: adding Accept-Language header tagging for analytics purposes.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch otel-accept-lang

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
Backend/Otel/OtelKernel.cs (1)

85-88: Accept-Language enrichment is solid; consider avoiding magic string and double-check consent expectations

The new Accept-Language tagging is implemented safely with TryGetValue and produces a sensible string via langs.ToString(). Two minor follow-ups to consider:

  • Use a constant (e.g., Microsoft.Net.Http.Headers.HeaderNames.AcceptLanguage) instead of the raw "Accept-Language" literal to avoid typos and ease reuse.
  • Today this tag is added for all requests, regardless of analyticsOn/consent. If your privacy/analytics policy expects all analytics-related attributes (even “non-PII” ones) to be gated by consent, you may want to condition this on the same consent signal used elsewhere; if Accept-Language is explicitly allowed outside consent, current behavior is fine.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 16e96db and ff48c31.

📒 Files selected for processing (1)
  • Backend/Otel/OtelKernel.cs (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: docker_build
  • GitHub Check: test_build (8.0.x)
  • GitHub Check: tox (3.12)
  • GitHub Check: Analyze (csharp)
🔇 Additional comments (1)
Backend/Otel/OtelKernel.cs (1)

101-103: Null-safe query check refactor looks good

The new if (!string.IsNullOrEmpty(request.RequestUri?.Query)) keeps prior behavior while simplifying the null checks and still avoids NullReferenceException when RequestUri is unset. No further changes needed from my side.

@codecov
Copy link

codecov bot commented Dec 11, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 85.66%. Comparing base (16e96db) to head (38e17db).
⚠️ Report is 17 commits behind head on master.

Additional details and impacted files
@@             Coverage Diff             @@
##           master    #4060       +/-   ##
===========================================
+ Coverage   74.55%   85.66%   +11.10%     
===========================================
  Files         294       54      -240     
  Lines       10897     4763     -6134     
  Branches     1366      587      -779     
===========================================
- Hits         8124     4080     -4044     
+ Misses       2378      539     -1839     
+ Partials      395      144      -251     
Flag Coverage Δ
backend 85.66% <ø> (ø)
frontend ?

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Backend/Otel/OtelKernel.cs (1)

80-86: Avoid setting empty Accept-Language tag; consider consent alignment

request.Headers.AcceptLanguage is a valid typed property on IHeaderDictionary and will compile. However, calling .ToString() on a missing header returns an empty string rather than skipping the tag. Consider checking for presence before tagging:

-                TrackSession(activity, request);
-                activity.SetTag("http.request.header.accept_language", request.Headers.AcceptLanguage.ToString());
+                TrackSession(activity, request);
+                var acceptLanguage = request.Headers.AcceptLanguage;
+                if (!StringValues.IsNullOrEmpty(acceptLanguage))
+                {
+                    activity.SetTag("http.request.header.accept_language", acceptLanguage.ToString());
+                }

Additionally, if product requirements mandate that this header should only be captured when analytics consent is enabled, gate this on the same consent signal already checked in TrackConsent().

🧹 Nitpick comments (1)
Backend/Otel/OtelKernel.cs (1)

95-101: HttpClient query tagging change looks good; keep an eye on PII in queries

The simplified null/empty check for request.RequestUri?.Query is correct and keeps the behavior (only tag when a non-empty query exists) while reducing nesting. request is non-null in this callback, so the remaining null-conditional on RequestUri is sufficient.

Given you are tagging the full url.query, just ensure that upstream callers don’t place secrets or sensitive PII in query strings, or consider redaction if that’s a risk.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ff48c31 and 38e17db.

📒 Files selected for processing (1)
  • Backend/Otel/OtelKernel.cs (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: docker_build
  • GitHub Check: test_build (8.0.x)
  • GitHub Check: Analyze (csharp)
  • GitHub Check: tox (3.12)

Copy link
Contributor

@jasonleenaylor jasonleenaylor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:lgtm:

@jasonleenaylor reviewed 1 of 1 files at r1, all commit messages.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved (waiting on @imnasnainaec)

@imnasnainaec imnasnainaec merged commit c96bbca into master Dec 15, 2025
16 checks passed
@imnasnainaec imnasnainaec deleted the otel-accept-lang branch December 15, 2025 21:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend 🟨Medium Medium-priority PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants