Commit Graph
9 Commits
Author SHA1 Message Date
Alaister YoungandAlaister Young 89ae80073d [FE-4400] feat(studio): shift-click range selection in Unified Logs (#50462)
Shift-clicking a row checkbox in Unified Logs now selects every row
between the last clicked row and the clicked one, following up on
#50381. Per review, the legacy logs table now uses react-data-grid's
native shift-click selection (the same mechanism as the table editor)
instead of the custom anchor logic from #50381, and Unified Logs matches
the grid's semantics.

**Semantics (all three tables):** a shift-click applies the clicked
checkbox's new state to every row between the last clicked row and the
clicked one. The last clicked row itself is untouched. In Unified Logs a
shift-click after the selection has been cleared is a plain toggle.

**Changed:**
- `LogTable` passes `selectedRows`, `onSelectedRowsChange`, and
`rowKeyGetter` to the grid and renders the checkbox through a small
`LogSelectCell` component using `useRowSelection`. The custom anchor
ref, its resets, and the inline toggle are gone. Checking a row still
closes the single-row side panel.
- `getShiftClickSelection` moved from the Logs utils to
`apps/studio/lib/shift-click-selection.ts` and rewritten to the grid's
rule. Only Unified Logs uses it now, via a `getShiftClickRowSelection`
adapter for TanStack Table's `RowSelectionState`. Tests cover both.
- Unified Logs owns a selection anchor ref and passes it into the column
generator. The checkbox cell handles `onClick` with the shift key,
computes the range over the table's displayed row model (so it spans
sort order and infinite-scrolled pages), and writes back through the
table's own selection setter. Shift mousedown is prevented so no text
selection spans rows.
- The `LogTable` test mock of react-data-grid now implements the grid's
row selection so the component tests exercise the native path.

## To test

- Postgres logs: click one checkbox, then shift-click a checkbox further
down. Every row in between should be checked and the action bar shows
the count. Repeat upward.
- Shift-click an already-checked row: it and the rows back to the last
clicked row uncheck, the last clicked row stays as it was.
- Checking a box closes the single-row side panel. Clicking a row body
clears the selection and opens the panel.
- Tab to a checkbox and press Space: it still toggles. Arrow keys plus
Shift+Space still toggle the focused row.
- Unified Logs: same shift-click behavior. Clear the selection or change
a filter, then shift-click: only that one row toggles. Scroll to load
more rows and shift-click across the boundary.
- Copy as JSON/Markdown and Explain with AI still use the selected rows
in both tables.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
  - Improved row selection in Settings Logs and Unified Logs.
- Shift-click now selects or deselects the range between the anchor row
and clicked row.
- Clicking an already selected row clears the relevant selection while
preserving the anchor row.
- Added more consistent checkbox, keyboard, and range-selection behavior
across log tables.
- Selecting a checkbox no longer opens the corresponding log, while
clicking the row continues to open it.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
2026-09-25 15:38:23 +08:00
Alaister YoungandAlaister Young 240bfce7f6 [FE-4198] feat(studio): select a range of logs with shift-click (#50381)
Shift-clicking a log row checkbox now selects every row between the last
clicked row and the clicked one, so you can grab a consecutive block of
logs to copy without checking each one. Applies everywhere the shared
`LogTable` renders: Postgres/API/Auth/Edge Functions logs and the Logs
Explorer.

**Added:**
- `getShiftClickSelection` in `Logs.utils.ts`: pure helper that computes
the next selection from the ordered row keys, the current selection, the
anchor row, and the clicked row. Adds the inclusive range in either
direction. If the whole range is already selected it deselects the range
instead. Falls back to a plain toggle when there's no usable anchor.
Covered by unit tests, plus `LogTable` component tests for range select,
the no-anchor fallback, anchor clearing, and range deselect.

**Changed:**
- `LogTable` tracks the last toggled row as the range anchor (a ref,
since it's only read in handlers). The anchor is set by plain clicks,
shift-clicks, and the Shift+Space row toggle, and cleared whenever the
selection becomes empty (toggling off the last row, plain row click,
Escape, action bar clear, select-all then deselect-all, or a new query
loading).
- The checkbox cell handles `onClick` instead of `onCheckedChange` so
the shift key is available. Keyboard Space on a focused checkbox still
toggles it, since Radix dispatches a click for it.
- A shift mousedown on the checkbox cell is prevented so the browser
doesn't start a text selection across rows.

Unified Logs has its own row selection (TanStack Table) and is not
changed here.

## To test

- Open any log page with a decent number of rows, e.g. Postgres logs.
Click one checkbox, then shift-click a checkbox several rows below.
Every row in between should be checked and the action bar should show
the count. Repeat upward.
- Shift-click a range that's already fully selected: the range should
clear, and rows outside it stay as they were.
- Plain-click a row's message text (not the checkbox): side panel opens
and the selection clears. A following shift-click should just toggle
that one row.
- Press Escape or the action bar's clear button, then shift-click: also
just a single toggle.
- Focus a row with the arrow keys, press Shift+Space, then shift-click a
lower checkbox: the range should extend from the keyboard-toggled row.
- Tab to a checkbox and press Space: it should still toggle.
- After a shift-click, confirm no text is highlighted across the rows.
- Copy as JSON/Markdown/CSV still copies the selected rows in display
order.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added shift-click range selection to the logs table for selecting or
deselecting consecutive rows.
  - Preserved single-row selection when range selection is unavailable.
- Improved selection behavior when clearing selections or changing log
queries, preventing stale range anchors.

- **Tests**
- Added coverage for forward and reverse range selection, deselection,
partial selections, fallback behavior, and input immutability.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
2026-09-16 18:18:28 +08:00
Jordi EnricandClaude Opus 4.8 ceff7b99bf fix(logs): guard chart query against unparseable timestamp params (#47485)
## Problem

The per-service logs pages (e.g. `/project/[ref]/logs/auth-logs`)
crashed with `RangeError: Invalid time value` (Sentry issue 7580074952).
`calcChartStart` guarded `iso_timestamp_start` only against falsy
values, so a truthy-but-unparseable timestamp (a malformed value in the
URL query params) produced an Invalid Date, which propagated through
`.add()` and threw when `startOffset.toISOString()` was called.

The bug is on the legacy (non-OTEL) chart query path. The OTEL bucket
helper had the same unguarded pattern; it did not crash but could skew
the chart bucket size.

## Fix

Validate parsed timestamps with `dayjs().isValid()` and fall back to
now, matching the existing empty-param behavior. Applied to both
`calcChartStart` (legacy) and `otelChartTruncFn` (OTEL).

- Valid params produce identical output (existing tests unaffected)
- Empty params still fall back to now
- Malformed input no longer throws

Added regression tests to `Logs.utils.test.ts` and
`Logs.utils.otel.test.ts`.

## How to test

- Run the logs unit tests: `pnpm test:studio` (or target
`Logs.utils.test.ts` and `Logs.utils.otel.test.ts`)
- In the dashboard, open a service logs page with a malformed timestamp
in the URL, e.g. `/project/<ref>/logs/auth-logs?its=not-a-date`
- Expected result: the page renders without crashing and the chart falls
back to the default (now-based) time range

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Improved log chart time-range handling by safely resolving missing or
invalid ISO timestamps via a shared timestamp resolver.
* Updated chart bucketing and timestamp conflict logic to use the
resolved endpoints, preventing errors and ensuring correct fallback
granularity (including minute-level bucketing when needed).
* **Tests**
* Added regression coverage to confirm chart query generation (including
OTEL queries) does not throw for unparseable start/end timestamps.
* Verified fallback behavior to minute-level bucketing and non-throwing
behavior for timestamp conflict handling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 17:41:30 +02:00
Jordi EnricandClaude Opus 4.8 27c1850a9a feat(logs): enforce a LIMIT clause in the log explorer (#47630)
## What

Enforces a `LIMIT` clause on Logs Explorer queries, replacing the
previous soft warning.

- Queries without a `LIMIT <n>` can no longer be run.
- Instead of the warning badge, the results box shows a clear "Add a
LIMIT to your query" message.
- The error clears as soon as a valid `LIMIT` is added.

## Why

Unbounded queries can scan very large amounts of data. This adds a UI
guardrail so a bounded result set is always requested.

## Notes

- New `checkForLimitClause` util detects `LIMIT <n>` outside of string
literals and comments (mirrors the existing WITH/ILIKE checks), with
unit tests.
- The missing-limit message reuses the existing error-rendering path via
a `missingLimit` reason, alongside `resourcesExceeded`.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
  * Log queries now require a `LIMIT` clause before they can run.
* A new on-screen message guides users to add a `LIMIT` when it’s
missing.

* **Bug Fixes**
* Improved log query validation to better detect valid `LIMIT` usage,
including mixed case, multiline queries, and avoidance of false matches
in comments, strings, or column names.
* Existing error messages continue to appear for other query limits and
failures.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 13:04:46 +02:00
Jordi Enric 0367047d31 fix(studio): classify auth log 4xx as warning, 5xx as error (#46851) 2026-06-11 19:51:58 +02:00
Jordi EnricandClaude Opus 4.7 a7dda67549 feat(studio): add Multigres logs collection for HA projects (#46499)
## Problem

High availability (Multigres) projects don't expose Multigres service
logs in the Studio logs UI, so users on HA projects have no entry point
to inspect them.

## Fix

Add a `Multigres` logs collection, gated behind the `multigresLogs`
ConfigCat flag **and** the project's `high_availability` flag
(`useShowMultigresLogs`):

- New `Multigres` entry in the logs sidebar `Collections`, linking to a
new `multigres-logs` page that queries the `multigres_logs` table.
- Wire `multigres_logs` through the logs constants, types, table SQL,
query type, and service labels.
- Row formatting: parse the JSON `event_message` and render `level`
through `SeverityFormatter` and `msg` through `TextFormatter`, matching
the other service collections (instead of dumping raw JSON).
- `WARN` severity is now styled like `WARNING` (amber), since Multigres
emits `level: WARN`.
- Log detail drawer: parse the JSON `event_message` and spread its keys
onto the log so each field (level, msg, query, error, connection_id,
etc.) renders as its own collapsible row.
- Single-log query omits the `metadata` column for `multigres_logs` (the
table has no such column), fixing an `INVALID_ARGUMENT` error when
opening the detail drawer.
- Event chart: parse the level out of `event_message` via `JSON_VALUE`
so error/warning bars are counted (the table has no top-level level
column).
- Add the `multigres_logs` source schema to the Field Reference drawer,
same gating.

## Why a feature flag

`high_availability` is an existing product feature that predates
Multigres, so existing HA projects could otherwise see a broken
collection querying a `multigres_logs` table they don't have. Requiring
the `multigresLogs` flag ships the feature dark and decouples rollout
from HA status. The flag must be created in ConfigCat before enabling;
until then `useFlag` returns false and the feature stays hidden.

## How to test

- Enable the `multigresLogs` flag (or override locally) and open a
project where `high_availability` is `true`.
- Navigate to `Logs`. Confirm a `Multigres` entry appears under
`Collections` (after `Replication`).
- Open it: the page loads at `/project/<ref>/logs/multigres-logs` and
queries `multigres_logs`.
- Confirm rows show a colored severity pill (including amber `WARN`) and
a readable message rather than raw JSON.
- Confirm the chart counts error/warning bars correctly.
- Click a row: the detail drawer shows each parsed field as its own row,
with no error.
- Open the Field Reference drawer and confirm `Multigres` is listed as a
source.
- With the flag off, or on a non-HA project, confirm the collection and
Field Reference source are both hidden.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Multigres added as a dedicated log source with its own Logs page,
sidebar entry, and query type.
* Log list and preview now parse Multigres payloads to surface
timestamp, severity, and formatted message.
* Multigres integrated into charting, prompt labels, and field-reference
UI (hidden unless enabled).
* New hook controls showing Multigres UI only when feature flag + HA
project condition are met.
* **Bug Fixes**
  * Severity rendering treats "WARN" the same as "WARNING".
* **Tests**
  * Unit tests added for Multigres parsing and the show-Multigres hook.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-03 12:00:19 +02:00
Ali Waseem 83992c55f7 feat(log-explorer): arrow key and deeper shortcuts for log explorer (#45989)
Closes
[FE-3378](https://linear.app/supabase/issue/FE-3378/featlogs-keyboard-shortcuts-for-function-logs-invocations-and-logs).

## Summary
Adds a shared shortcut registry for every `LogsPreviewer` surface —
Function Logs, Function Invocations, and the Logs Explorer — and brings
the grid keyboard model in line with the Auth Users / Table Editor
patterns.

## Shortcuts

| Key | Action |
| --- | --- |
| `↑` / `↓` | Move single-row selection; opens side panel |
| `Shift+Space` | Toggle current row in multi-select |
| `Mod+A` | Toggle all visible rows in multi-select |
| `Esc` | Staged: clear multi-select → close side panel |
| `Shift+R` | Refresh logs |
| `Shift+H` | Toggle histogram |
| `Shift+L` | Load older logs |
| `Shift+P` | Open time range picker |
| `Mod+Shift+J / M / C` | Copy selected rows as JSON / Markdown / CSV
(existing global handler) |

## Other changes
- `ShortcutTooltip` on search, refresh, histogram, load older, and
time-picker controls.
- `onSearchInputEscape` wired on the logs search bar (clear → blur).
- Visual row highlight (`rdg-row--focused`) when a row is
keyboard-focused or multi-selected.
- Multi-select copy dropdown gains a **Copy as CSV** entry and shows the
keybind on each item via `ShortcutBadge`.
- Manual arrow-nav (`navigate()`) updates `selectedRow` directly without
going through `onRowClick`, so multi-select checkmarks survive keyboard
navigation.

## Test plan
- [x] Function Logs and Function Invocations: all shortcuts above fire
while the page is mounted, no firing in other tabs.
- [x] Logs Explorer: same shortcuts work; copy keybinds still copy *all*
rows when nothing is multi-selected.
- [x] Arrow keys on first load select the first row even when the focus
sink is the active element.
- [x] Selecting rows via checkbox or `Shift+Space`, then pressing arrow
keys, preserves the checkmarks.
- [x] Escape on a populated search input clears it; Escape on an empty
input blurs it.
- [x] Esc with multi-select active clears the selection before closing
the side panel.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* CSV export for log selections (adds CSV alongside JSON and Markdown).
* New logs-preview keyboard shortcuts: search focus, refresh, chart
toggle, date picker, load older, navigation, and selection.

* **Improvements**
  * Shortcut badges and tooltip integration across the logs UI.
* Search input focus/ref support and controlled date-picker visibility.
  * Better no-results/error rendering and expanded copy dropdown sizing.

* **Tests**
  * Added CSV formatting tests covering RFC 4180 edge cases.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/45989)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-19 15:25:47 +00:00
Jordi EnricandClaude Sonnet 4.6 e9d951a65c feat(logs): show edge function name in logs FE-2798 (#43967)
## Problem

The edge function logs table at
`/observability/logs/edge-functions-logs` did not show which edge
function was called. Users had to open individual log entries to find
the function name, even though the information is available in the log
data.

## Fix

- Added `request.pathname` to the SQL SELECT query for
`function_edge_logs` so the pathname is returned with each row.
- Added `extractEdgeFunctionName` utility that parses the last path
segment from the pathname (e.g. `/functions/v1/hello-world-1` becomes
`hello-world-1`).
- Updated `FunctionsEdgeColumnRender` to display the function name
between the HTTP method and the log ID columns.
- Added unit tests for `extractEdgeFunctionName` covering normal paths,
null/undefined, non-string values, and pathnames without slashes.

<img width="1472" height="776" alt="CleanShot 2026-03-19 at 13 18 47@2x"
src="https://github.com/user-attachments/assets/e437f7df-7aab-4ea5-b421-95bab3923605"
/>


## How to test

- Navigate to Logs and Analytics, then Edge Functions logs.
- Confirm each row now shows the function name (e.g. `hello-world-1`)
between the HTTP method and the log ID.
- Confirm rows without a pathname (e.g. non-platform or self-hosted)
still render without errors.
- Confirm clicking a row still opens the log detail panel correctly.

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 09:39:22 +01:00
Jordi Enric 4b994fcb54 feat: copy multiple logs (#43218)
Allows users to select logs and copy their contents for debugging, or
pass them on to assistant with one click.

## To test
- go to logs or log explorer
- select some logs
- try copying as json, markdown, or sending it to assistant.
2026-03-06 13:24:37 +01:00