Skip to content

chore: add logging event for drill to detail - #42563

Open
ayush-sharaf wants to merge 3 commits into
apache:masterfrom
ayush-sharaf:chore/drill-to-detail-log-event
Open

chore: add logging event for drill to detail#42563
ayush-sharaf wants to merge 3 commits into
apache:masterfrom
ayush-sharaf:chore/drill-to-detail-log-event

Conversation

@ayush-sharaf

@ayush-sharaf ayush-sharaf commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

SUMMARY

Drill By is instrumented with four log events (added in #23854): drill_by_modal_opened, further_drill_by, drill_by_edit_chart and drill_by_breadcrumb_clicked. Its sibling feature Drill to Detail has none, so there is no way to tell from the logs table that a user opened Drill to Detail, or on which chart.

It cannot be reconstructed server-side either. Opening the modal issues exactly one request, POST /datasource/samples, whose body is built by getDrillPayload() as {granularity, time_range, filters, extras} and whose query args are datasource_type, datasource_id, dashboard_id, force, page, per_page — none of which reference a chart. Because one dataset commonly backs many charts on the same dashboard, datasource_id + dashboard_id is not enough to identify the chart.

DatasetRestApi.get_drill_info does write a log row, but it is not a drill signal: useDatasetDrillInfo prefetches it when the chart renders (gated only on canDrillToDetail), so it emits one row per dataset per dashboard load even when the user never drills, and its payload carries only pk (the dataset id) and rison.dashboard_id.

This PR adds LOG_ACTIONS_DRILL_TO_DETAIL_MODAL_OPENED (drill_to_detail_modal_opened), dispatched from DrillDetailModal with slice_id, mirroring DrillByModal. Because both entry points — the chart header ⋮ menu and the right-click context menu — render this same modal, one dispatch covers both.

Implementation note. Unlike DrillByModal, which mounts when it is opened, DrillDetailModal stays mounted for the lifetime of the chart and is toggled via its showModal prop. The effect is therefore gated on showModal rather than firing on mount, so no event is emitted while the modal is closed. Reopening the modal emits a new event, which is the intended behaviour.

DrillDetailModal already receives chartId as a prop and already resolves the chart name from sliceEntities to render its own title, so no new data plumbing was needed.

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

Not applicable — no UI change.

TESTING INSTRUCTIONS

Two unit tests are added to DrillDetailModal.test.tsx:

  • should log an event when the modal is opened — asserts logEvent is called with drill_to_detail_modal_opened and { slice_id }.
  • should not log an event while the modal is closed — renders with showModal={false} and asserts nothing is logged.
npm run test -- src/components/Chart/DrillDetail/DrillDetailModal.test.tsx

Manually:

  1. Open a dashboard containing a chart built on a drillable dataset.
  2. Open the chart's ⋮ menu and click Drill to detail (and separately, right-click a data point and use Drill to detail by).
  3. Confirm a drill_to_detail_modal_opened event is recorded with the correct slice_id — visible in the /superset/log/ request payload, or in the logs table with EVENT_LOGGER configured.
  4. Load the dashboard without drilling and confirm no such event is emitted.

ADDITIONAL INFORMATION

  • Has associated issue: Fixes Drill to Detail emits no log event, unlike Drill By #42562
  • Required feature flags:
  • Changes UI
  • Includes DB Migration (follow approval process in SIP-59)
    • Migration is atomic, supports rollback & is backwards-compatible
    • Confirm DB migration upgrade and downgrade tested
    • Runtime estimates and downtime expectations provided
  • Introduces new feature or API
  • Removes existing feature or API

Drill By is instrumented with four log events (drill_by_modal_opened,
further_drill_by, drill_by_edit_chart, drill_by_breadcrumb_clicked), but its
sibling feature Drill to Detail has none, so there is no way to tell that a user
opened Drill to Detail, or on which chart.

It cannot be reconstructed server-side either. Opening the modal issues a single
request, POST /datasource/samples, whose body is built by getDrillPayload() as
{granularity, time_range, filters, extras} with query args
datasource_type/datasource_id/dashboard_id/force/page/per_page — none of which
reference a chart. Since one dataset commonly backs many charts on the same
dashboard, datasource_id + dashboard_id cannot identify the chart.

DatasetRestApi.get_drill_info does log, but it is not a drill signal:
useDatasetDrillInfo prefetches it when the chart renders, so it emits a row per
dataset per dashboard load even when the user never drills, and carries only pk
(the dataset id) and rison.dashboard_id.

Adds LOG_ACTIONS_DRILL_TO_DETAIL_MODAL_OPENED, dispatched from DrillDetailModal
with slice_id, mirroring DrillByModal. This covers both entry points — the chart
header menu and the right-click context menu — since both render this modal.

Unlike DrillByModal, which mounts when opened, DrillDetailModal stays mounted
and is toggled via the showModal prop, so the effect is gated on showModal to
avoid firing on mount while the modal is closed.
@dosubot dosubot Bot added dashboard:drill-to-detail logging Creates a UI or API endpoint that could benefit from logging. labels Jul 29, 2026
@bito-code-review

bito-code-review Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #32bb1e

Actionable Suggestions - 0
Review Details
  • Files reviewed - 3 · Commit Range: 04cb65f..04cb65f
    • superset-frontend/src/components/Chart/DrillDetail/DrillDetailModal.test.tsx
    • superset-frontend/src/components/Chart/DrillDetail/DrillDetailModal.tsx
    • superset-frontend/src/logger/LogUtils.ts
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful
    • Eslint (Linter) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

Comment on lines +117 to +125
useEffect(() => {
if (showModal) {
dispatch(
logEvent(LOG_ACTIONS_DRILL_TO_DETAIL_MODAL_OPENED, {
slice_id: chartId,
}),
);
}
}, [dispatch, showModal, chartId]);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggestion: Because chartId is an effect dependency, changing the chart identity while the persistent modal remains open reruns this effect and records another “opened” event without a new open transition. Track the previous showModal value and log only when it changes from false to true, while using the current chart ID for that transition. [stale reference]

Severity Level: Major ⚠️
- ⚠️ Duplicate Drill to Detail analytics rows can be recorded.
- ⚠️ Chart-level modal-open metrics may overcount user openings.
- ⚠️ Dashboard logging becomes inaccurate when chart identity changes in-place.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** superset-frontend/src/components/Chart/DrillDetail/DrillDetailModal.tsx
**Line:** 117:125
**Comment:**
	*Stale Reference: Because `chartId` is an effect dependency, changing the chart identity while the persistent modal remains open reruns this effect and records another “opened” event without a new open transition. Track the previous `showModal` value and log only when it changes from false to true, while using the current chart ID for that transition.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the review. I looked into this and I don't believe it's reachable with the current usage, so I'd rather not add the extra state.

DrillDetailModal is rendered from two places, and in both the chartId is fixed for the lifetime of the mounted instance:

  • SliceHeaderControls renders it with chartId={slice.slice_id}, and that component is rendered per slice.
  • ChartContextMenu renders it with chartId={id}, and that component is rendered per chart inside ChartRenderer.

So there is no path where a mounted instance's chartId changes while showModal stays true. On top of that the modal is modal — it blocks interaction with the dashboard underneath while open — so a chart swap under an open modal isn't reachable either.

Given that, a useRef transition guard would be extra state to keep in sync with no behavioural difference today. I'd prefer to keep the effect as it is and revisit if a future caller ever shares one modal instance across charts.

Worth noting the suggested snippet also initialises the ref with useRef(showModal), which would swallow the event for a component that mounts with the modal already open. If we do add a guard later, it should start from false.

The existing tests cover the behaviour: one asserts the event fires with the correct slice_id when the modal is opened, and another asserts nothing is logged while it is closed.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Customized review instruction saved!

Instruction:

Do not flag duplicate modal-open analytics caused by chart identity changes when each modal instance has a chart ID fixed for its lifetime; only flag this when a modal instance can be reused across charts while remaining open.

Applied to:

  • superset-frontend/src/components/Chart/DrillDetail/DrillDetailModal.tsx

💡 To manage or update this instruction, visit: CodeAnt AI Settings

@bito-code-review

Copy link
Copy Markdown
Contributor

The flagged issue is correct. Because chartId is included in the useEffect dependency array, the logging effect will re-run whenever chartId changes, even if the modal remains open, leading to duplicate analytics events. To resolve this, you should track the previous showModal state using a useRef hook and only trigger the log event when showModal transitions from false to true.

Here is the corrected implementation for superset-frontend/src/components/Chart/DrillDetail/DrillDetailModal.tsx:

  const prevShowModal = useRef(showModal);
  useEffect(() => {
    if (showModal && !prevShowModal.current) {
      dispatch(
        logEvent(LOG_ACTIONS_DRILL_TO_DETAIL_MODAL_OPENED, {
          slice_id: chartId,
        }),
      );
    }
    prevShowModal.current = showModal;
  }, [dispatch, showModal, chartId]);

Would you like me to fetch all other comments on this PR to validate and implement fixes for them as well?

superset-frontend/src/components/Chart/DrillDetail/DrillDetailModal.tsx

const prevShowModal = useRef(showModal);
  useEffect(() => {
    if (showModal && !prevShowModal.current) {
      dispatch(
        logEvent(LOG_ACTIONS_DRILL_TO_DETAIL_MODAL_OPENED, {
          slice_id: chartId,
        }),
      );
    }
    prevShowModal.current = showModal;
  }, [dispatch, showModal, chartId]);

@codecov

codecov Bot commented Jul 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 65.33%. Comparing base (673f928) to head (9dc25e7).

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #42563      +/-   ##
==========================================
- Coverage   65.33%   65.33%   -0.01%     
==========================================
  Files        2803     2803              
  Lines      158490   158495       +5     
  Branches    36178    36179       +1     
==========================================
+ Hits       103557   103559       +2     
- Misses      52922    52924       +2     
- Partials     2011     2012       +1     
Flag Coverage Δ
javascript 71.47% <100.00%> (+<0.01%) ⬆️

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

☔ View full report in Codecov by Harness.
📢 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.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR adds frontend instrumentation for the Drill to Detail feature by emitting a dedicated log event when the modal is opened, enabling analytics to identify when a drill occurs and which chart (slice) initiated it.

Changes:

  • Added a new log action constant: drill_to_detail_modal_opened.
  • Dispatched the new logEvent from DrillDetailModal gated by showModal (so it only fires on open, not on mount).
  • Added unit tests verifying the event fires when opened and does not fire while closed.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
superset-frontend/src/logger/LogUtils.ts Adds the new LOG_ACTIONS_DRILL_TO_DETAIL_MODAL_OPENED constant.
superset-frontend/src/components/Chart/DrillDetail/DrillDetailModal.tsx Emits drill_to_detail_modal_opened with { slice_id: chartId } when showModal becomes true.
superset-frontend/src/components/Chart/DrillDetail/DrillDetailModal.test.tsx Adds tests to assert the event is logged on open and not logged while closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dashboard:drill-to-detail logging Creates a UI or API endpoint that could benefit from logging. size/M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Drill to Detail emits no log event, unlike Drill By

3 participants