mirror of
https://github.com/supabase/supabase.git
synced 2026-09-06 09:59:03 +08:00
## Problem Workers log views were limited to the most recent 24 hours and could not be narrowed by event text or HTTP method. ## Fix Adds selectable time ranges, event-message search, and an HTTP-method filter for invocation logs. Filters are applied in the analytics query and included in the cache key. ## How to test - Open a worker and select the Invocations tab. - Change the time range, enter an event message, and select a method. - Expected result: only matching invocation logs are shown. - Open Logs or Activity. - Expected result: message and time filters are available; the method filter is hidden. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added worker log filtering by date range and event message. * Applied a default 24-hour time range to log searches. * Improved filter controls and updated empty-state messaging to reflect the selected range. * **Bug Fixes** * Improved filtering accuracy and safer handling of special characters in event messages. * **Tests** * Added coverage for date-range and message-filter query behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
89 lines
3.2 KiB
TypeScript
89 lines
3.2 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
|
|
import { workersKeys } from './keys'
|
|
import { parseWorkerLogRows, workerLogsSql } from './worker-logs-query'
|
|
|
|
describe('workerLogsSql', () => {
|
|
it('reads one worker stream, newest first', () => {
|
|
expect(workerLogsSql('embed', 'output')).toBe(
|
|
"select id, timestamp, severity_text as severity, event_message as message from logs where log_attributes['worker'] = 'embed' and log_attributes['source'] = 'worker_guest_logs' order by timestamp desc limit 100"
|
|
)
|
|
})
|
|
|
|
it('filters by event message before applying the limit', () => {
|
|
expect(workerLogsSql('embed', 'requests', { message: 'timeout' })).toBe(
|
|
"select id, timestamp, severity_text as severity, event_message as message from logs where log_attributes['worker'] = 'embed' and log_attributes['source'] = 'worker_ingress_logs' and event_message ilike '%timeout%' order by timestamp desc limit 100"
|
|
)
|
|
})
|
|
|
|
it('names the right stream for each tab', () => {
|
|
expect(workerLogsSql('embed', 'requests')).toContain("'worker_ingress_logs'")
|
|
expect(workerLogsSql('embed', 'builds')).toContain("'worker_api_logs'")
|
|
})
|
|
|
|
it('escapes a worker name rather than interpolating it raw', () => {
|
|
expect(workerLogsSql("embed' or '1'='1", 'output')).toContain(
|
|
"log_attributes['worker'] = 'embed'' or ''1''=''1'"
|
|
)
|
|
})
|
|
|
|
it('escapes filter values rather than interpolating them raw', () => {
|
|
expect(workerLogsSql('embed', 'requests', { message: "can't connect" })).toContain(
|
|
"event_message ilike '%can''t connect%'"
|
|
)
|
|
})
|
|
})
|
|
|
|
describe('workersKeys.logs', () => {
|
|
it('includes the selected time range and filters', () => {
|
|
expect(
|
|
workersKeys.logs('project-ref', 'embed', 'requests', {
|
|
iso_timestamp_start: '2026-09-01T12:00:00.000Z',
|
|
iso_timestamp_end: '2026-09-02T12:00:00.000Z',
|
|
message: 'timeout',
|
|
})
|
|
).toEqual([
|
|
'projects',
|
|
'project-ref',
|
|
'worker',
|
|
'embed',
|
|
'logs',
|
|
'requests',
|
|
{
|
|
iso_timestamp_start: '2026-09-01T12:00:00.000Z',
|
|
iso_timestamp_end: '2026-09-02T12:00:00.000Z',
|
|
message: 'timeout',
|
|
},
|
|
])
|
|
})
|
|
})
|
|
|
|
describe('parseWorkerLogRows', () => {
|
|
it('shapes rows for the logs table with a numeric timestamp', () => {
|
|
const [row] = parseWorkerLogRows([
|
|
{ id: 'a', timestamp: '2026-08-24T10:00:00.000000', severity: 'ERROR', message: 'boom' },
|
|
])
|
|
expect(row.id).toBe('a')
|
|
expect(row.event_message).toBe('boom')
|
|
expect(row.severity_text).toBe('ERROR')
|
|
expect(typeof row.timestamp).toBe('number')
|
|
expect(Number.isFinite(row.timestamp)).toBe(true)
|
|
})
|
|
|
|
it('falls back to empty strings for null severity and message', () => {
|
|
const [row] = parseWorkerLogRows([
|
|
{ id: 'a', timestamp: '2026-08-24T10:00:00.000000', severity: null, message: null },
|
|
])
|
|
expect(row.severity_text).toBe('')
|
|
expect(row.event_message).toBe('')
|
|
})
|
|
|
|
it('returns an empty array for a missing result', () => {
|
|
expect(parseWorkerLogRows(undefined)).toEqual([])
|
|
})
|
|
|
|
it('rejects a malformed row rather than passing bad data to the table', () => {
|
|
expect(() => parseWorkerLogRows([{ timestamp: '2026-08-24T10:00:00.000000' }])).toThrow()
|
|
})
|
|
})
|