| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788 |
- import { IS_PLATFORM } from 'common'
- import dayjs from 'dayjs'
- import type { DatetimeHelper, FilterTableSet, LogTemplate } from './Logs.types'
- import { DOCS_URL } from '@/lib/constants'
- export const LOGS_EXPLORER_DOCS_URL = `${DOCS_URL}/guides/platform/logs#querying-with-the-logs-explorer`
- export const LOGS_LARGE_DATE_RANGE_DAYS_THRESHOLD = 2 // IN DAYS
- export const TEMPLATES: LogTemplate[] = [
- {
- label: 'Recent Errors',
- mode: 'simple',
- searchString: '[Ee]rror|\\s[45][0-9][0-9]\\s',
- for: ['api'],
- },
- {
- label: 'Commits',
- mode: 'simple',
- searchString: 'COMMIT',
- for: ['database'],
- },
- {
- label: 'Commits By User',
- description: 'Count of commits made by users on the database',
- mode: 'custom',
- searchString: `select
- p.user_name,
- count(*) as count
- from postgres_logs
- left join unnest(metadata) as m on true
- left join unnest(m.parsed) as p on true
- where
- regexp_contains(event_message, 'COMMIT')
- group by
- p.user_name
- `,
- for: ['database'],
- },
- {
- label: 'Metadata IP',
- description: 'List all IP addresses that used the Briven API',
- mode: 'custom',
- searchString: `select
- cast(timestamp as datetime) as timestamp,
- h.x_real_ip
- from edge_logs
- left join unnest(metadata) as m on true
- left join unnest(m.request) as r on true
- left join unnest(r.headers) as h on true
- where h.x_real_ip is not null
- `,
- for: ['api'],
- },
- {
- label: 'Requests by Geography',
- description: 'List all ISO 3166-1 alpha-2 country codes that used the Briven API',
- mode: 'custom',
- searchString: `select
- cf.country,
- count(*) as count
- from edge_logs
- left join unnest(metadata) as m on true
- left join unnest(m.request) as r on true
- left join unnest(r.cf) as cf on true
- group by
- cf.country
- order by
- count desc
- `,
- for: ['api'],
- },
- {
- label: 'Slow Response Time',
- mode: 'custom',
- description: 'List all Briven API requests that are slow',
- searchString: `select
- cast(timestamp as datetime) as timestamp,
- event_message,
- r.origin_time
- from edge_logs
- cross join unnest(metadata) as m
- cross join unnest(m.response) as r
- where
- r.origin_time > 1000
- order by
- timestamp desc
- limit 100
- `,
- for: ['api'],
- },
- {
- label: '500 Request Codes',
- description: 'List all Briven API requests that responded witha 5XX status code',
- mode: 'custom',
- searchString: `select
- cast(timestamp as datetime) as timestamp,
- event_message,
- r.status_code
- from edge_logs
- cross join unnest(metadata) as m
- cross join unnest(m.response) as r
- where
- r.status_code >= 500
- order by
- timestamp desc
- limit 100
- `,
- for: ['api'],
- },
- {
- label: 'Top Paths',
- description: 'List the most requested Briven API paths',
- mode: 'custom',
- searchString: `select
- r.path as path,
- r.search as params,
- count(timestamp) as c
- from edge_logs
- cross join unnest(metadata) as m
- cross join unnest(m.request) as r
- group by
- path,
- params
- order by
- c desc
- limit 100
- `,
- for: ['api'],
- },
- {
- label: 'REST Requests',
- description: 'List all PostgREST requests',
- mode: 'custom',
- searchString: `select
- cast(timestamp as datetime) as timestamp,
- event_message
- from edge_logs
- cross join unnest(metadata) as m
- cross join unnest(m.request) as r
- where
- path like '%rest/v1%'
- order by
- timestamp desc
- limit 100
- `,
- for: ['api'],
- },
- {
- label: 'Errors',
- description: 'List all Postgres error messages with ERROR, FATAL, or PANIC severity',
- mode: 'custom',
- searchString: `select
- cast(t.timestamp as datetime) as timestamp,
- p.error_severity,
- event_message
- from postgres_logs as t
- cross join unnest(metadata) as m
- cross join unnest(m.parsed) as p
- where
- p.error_severity in ('ERROR', 'FATAL', 'PANIC')
- order by
- timestamp desc
- limit 100
- `,
- for: ['database'],
- },
- {
- label: 'Error Count by User',
- description: 'Count of errors by users',
- mode: 'custom',
- searchString: `select
- count(t.timestamp) as count,
- p.user_name,
- p.error_severity
- from postgres_logs as t
- cross join unnest(metadata) as m
- cross join unnest(m.parsed) as p
- where
- p.error_severity in ('ERROR', 'FATAL', 'PANIC')
- group by
- p.user_name,
- p.error_severity
- order by
- count desc
- limit 100
- `,
- for: ['database'],
- },
- {
- label: 'Auth Endpoint Events',
- description: 'Endpoint events filtered by path',
- mode: 'custom',
- searchString: `select
- t.timestamp,
- event_message
- from auth_logs as t
- where
- regexp_contains(event_message,"level.{3}(info|warning||error|fatal)")
- -- and regexp_contains(event_message,"path.{3}(/token|/recover|/signup|/otp)")
- limit 100
- `,
- for: ['database'],
- },
- {
- label: 'Auth Audit Logs',
- description: 'Audit logs for auth events',
- mode: 'custom',
- searchString: `select
- cast(timestamp as datetime) as timestamp,
- event_message, metadata
- from auth_audit_logs
- limit 10
- `,
- for: ['database'],
- },
- {
- label: 'Storage Object Requests',
- description: 'Number of requests done on Storage Objects',
- mode: 'custom',
- searchString: `select
- r.method as http_verb,
- r.path as filepath,
- count(*) as num_requests
- from edge_logs
- cross join unnest(metadata) as m
- cross join unnest(m.request) AS r
- cross join unnest(r.headers) AS h
- where
- path like '%storage/v1/object/%'
- group by
- r.path, r.method
- order by
- num_requests desc
- limit 100
- `,
- for: ['api'],
- },
- {
- label: 'Storage Egress Requests',
- description: 'Check the number of requests done on Storage Affecting Egress',
- mode: 'custom',
- searchString: `select
- request.method as http_verb,
- request.path as filepath,
- (responseHeaders.cf_cache_status = 'HIT') as cached,
- count(*) as num_requests
- from
- edge_logs
- cross join unnest(metadata) as metadata
- cross join unnest(metadata.request) as request
- cross join unnest(metadata.response) as response
- cross join unnest(response.headers) as responseHeaders
- where
- (path like '%storage/v1/object/%' or path like '%storage/v1/render/%')
- and request.method = 'GET'
- group by 1, 2, 3
- order by num_requests desc
- limit 100;
- `,
- for: ['api'],
- },
- {
- label: 'Storage Top Cache Misses',
- description: 'The top Storage requests that miss caching',
- mode: 'custom',
- searchString: `select
- r.path as path,
- r.search as search,
- count(id) as count
- from edge_logs f
- cross join unnest(f.metadata) as m
- cross join unnest(m.request) as r
- cross join unnest(m.response) as res
- cross join unnest(res.headers) as h
- where starts_with(r.path, '/storage/v1/object')
- and r.method = 'GET'
- and h.cf_cache_status in ('MISS', 'NONE/UNKNOWN', 'EXPIRED', 'BYPASS', 'DYNAMIC')
- group by path, search
- order by count desc
- limit 100;
- `,
- for: ['api'],
- },
- ]
- const _SQL_FILTER_COMMON = {
- search_query: (value: string) => `regexp_contains(event_message, '${value}')`,
- }
- export const SQL_FILTER_TEMPLATES: any = {
- postgres_logs: {
- ..._SQL_FILTER_COMMON,
- database: (value: string) => `identifier = '${value}'`,
- 'severity.error': `parsed.error_severity in ('ERROR', 'FATAL', 'PANIC')`,
- 'severity.noError': `parsed.error_severity not in ('ERROR', 'FATAL', 'PANIC')`,
- 'severity.log': `parsed.error_severity = 'LOG'`,
- },
- edge_logs: {
- ..._SQL_FILTER_COMMON,
- database: (value: string) => `identifier = '${value}'`,
- 'status_code.error': `response.status_code between 500 and 599`,
- 'status_code.success': `response.status_code between 200 and 299`,
- 'status_code.warning': `response.status_code between 400 and 499`,
- 'product.database': `request.path like '/rest/%' or request.path like '/graphql/%'`,
- 'product.storage': `request.path like '/storage/%'`,
- 'product.auth': `request.path like '/auth/%'`,
- 'product.realtime': `request.path like '/realtime/%'`,
- 'method.get': `request.method = 'GET'`,
- 'method.post': `request.method = 'POST'`,
- 'method.put': `request.method = 'PUT'`,
- 'method.patch': `request.method = 'PATCH'`,
- 'method.delete': `request.method = 'DELETE'`,
- 'method.options': `request.method = 'OPTIONS'`,
- },
- function_edge_logs: {
- ..._SQL_FILTER_COMMON,
- 'status_code.error': `response.status_code between 500 and 599`,
- 'status_code.success': `response.status_code between 200 and 299`,
- 'status_code.warning': `response.status_code between 400 and 499`,
- },
- function_logs: {
- ..._SQL_FILTER_COMMON,
- 'severity.error': `metadata.level = 'error'`,
- 'severity.notError': `metadata.level != 'error'`,
- 'severity.log': `metadata.level = 'log'`,
- 'severity.info': `metadata.level = 'info'`,
- 'severity.debug': `metadata.level = 'debug'`,
- 'severity.warn': `metadata.level = 'warn'`,
- },
- auth_logs: {
- ..._SQL_FILTER_COMMON,
- 'severity.error': `metadata.level = 'error' or metadata.level = 'fatal'`,
- 'severity.warning': `metadata.level = 'warning'`,
- 'severity.info': `metadata.level = 'info'`,
- 'status_code.server_error': `cast(metadata.status as int64) between 500 and 599`,
- 'status_code.client_error': `cast(metadata.status as int64) between 400 and 499`,
- 'status_code.redirection': `cast(metadata.status as int64) between 300 and 399`,
- 'status_code.success': `cast(metadata.status as int64) between 200 and 299`,
- 'endpoints.admin': `REGEXP_CONTAINS(metadata.path, "/admin")`,
- 'endpoints.signup': `REGEXP_CONTAINS(metadata.path, "/signup|/invite|/verify")`,
- 'endpoints.authentication': `REGEXP_CONTAINS(metadata.path, "/token|/authorize|/callback|/otp|/magiclink")`,
- 'endpoints.recover': `REGEXP_CONTAINS(metadata.path, "/recover")`,
- 'endpoints.user': `REGEXP_CONTAINS(metadata.path, "/user")`,
- 'endpoints.logout': `REGEXP_CONTAINS(metadata.path, "/logout")`,
- },
- realtime_logs: {
- ..._SQL_FILTER_COMMON,
- },
- storage_logs: {
- ..._SQL_FILTER_COMMON,
- },
- postgrest_logs: {
- ..._SQL_FILTER_COMMON,
- database: (value: string) => `identifier = '${value}'`,
- },
- pgbouncer_logs: {
- ..._SQL_FILTER_COMMON,
- },
- supavisor_logs: {
- ..._SQL_FILTER_COMMON,
- database: (value: string) => `m.project like '${value}%'`,
- },
- pg_upgrade_logs: {
- ..._SQL_FILTER_COMMON,
- },
- pg_cron_logs: {
- ..._SQL_FILTER_COMMON,
- },
- etl_replication_logs: {
- ..._SQL_FILTER_COMMON,
- pipeline_id: (value: string | number) => `pipeline_id = ${value}`,
- },
- }
- export enum LogsTableName {
- EDGE = 'edge_logs',
- POSTGRES = 'postgres_logs',
- FUNCTIONS = 'function_logs',
- FN_EDGE = 'function_edge_logs',
- AUTH = 'auth_logs',
- AUTH_AUDIT = 'auth_audit_logs',
- REALTIME = 'realtime_logs',
- STORAGE = 'storage_logs',
- POSTGREST = 'postgrest_logs',
- SUPAVISOR = 'supavisor_logs',
- PGBOUNCER = 'pgbouncer_logs',
- PG_UPGRADE = 'pg_upgrade_logs',
- PG_CRON = 'pg_cron_logs',
- ETL = 'etl_replication_logs',
- }
- export const LOGS_TABLES = {
- api: LogsTableName.EDGE,
- database: LogsTableName.POSTGRES,
- functions: LogsTableName.FUNCTIONS,
- fn_edge: LogsTableName.FN_EDGE,
- auth: LogsTableName.AUTH,
- realtime: LogsTableName.REALTIME,
- storage: LogsTableName.STORAGE,
- postgrest: LogsTableName.POSTGREST,
- supavisor: LogsTableName.SUPAVISOR,
- pg_upgrade: LogsTableName.PG_UPGRADE,
- pg_cron: LogsTableName.POSTGRES,
- pgbouncer: LogsTableName.PGBOUNCER,
- etl: LogsTableName.ETL,
- }
- export const LOGS_SOURCE_DESCRIPTION = {
- [LogsTableName.EDGE]: 'Logs obtained from the network edge, containing all API requests',
- [LogsTableName.POSTGRES]: 'Database logs obtained directly from Postgres',
- [LogsTableName.FUNCTIONS]: 'Function logs generated from runtime execution',
- [LogsTableName.FN_EDGE]: 'Function call logs, containing the request and response',
- [LogsTableName.AUTH]: 'Errors, warnings, and performance details from the auth service',
- [LogsTableName.AUTH_AUDIT]: 'Audit records of user signups, logins, and account changes',
- [LogsTableName.REALTIME]: 'Realtime server for Postgres logical replication broadcasting',
- [LogsTableName.STORAGE]: 'Object storage logs',
- [LogsTableName.POSTGREST]: 'RESTful API web server logs',
- [LogsTableName.SUPAVISOR]: 'Shared connection pooler logs for PostgreSQL',
- [LogsTableName.PGBOUNCER]: 'Dedicated connection pooler for PostgreSQL',
- [LogsTableName.PG_UPGRADE]: 'Logs generated by the Postgres version upgrade process',
- [LogsTableName.PG_CRON]: 'Postgres logs from pg_cron cron jobs',
- [LogsTableName.ETL]: 'Logs from the replication process',
- }
- export const FILTER_OPTIONS: FilterTableSet = {
- // Postgres logs
- postgres_logs: {
- severity: {
- label: 'Severity',
- key: 'severity',
- options: [
- {
- key: 'error',
- label: 'Error',
- description: 'Show all events with ERROR, PANIC, or FATAL',
- },
- {
- key: 'noError',
- label: 'No Error',
- description: 'Show all non-error events',
- },
- {
- key: 'log',
- label: 'Log',
- description: 'Show all events that are log severity',
- },
- ],
- },
- },
- // Edge logs
- edge_logs: {
- status_code: {
- label: 'Status',
- key: 'status_code',
- options: [
- {
- key: 'error',
- label: 'Error',
- description: '500 error codes',
- },
- {
- key: 'success',
- label: 'Success',
- description: '200 codes',
- },
- {
- key: 'warning',
- label: 'Warning',
- description: '400 codes',
- },
- ],
- },
- product: {
- label: 'Product',
- key: 'product',
- options: [
- {
- key: 'database',
- label: 'Database',
- description: '',
- },
- {
- key: 'auth',
- label: 'Auth',
- description: '',
- },
- {
- key: 'storage',
- label: 'Storage',
- description: '',
- },
- {
- key: 'realtime',
- label: 'Realtime',
- description: '',
- },
- ],
- },
- method: {
- label: 'Method',
- key: 'method',
- options: [
- {
- key: 'get',
- label: 'GET',
- description: '',
- },
- {
- key: 'options',
- label: 'OPTIONS',
- description: '',
- },
- {
- key: 'put',
- label: 'PUT',
- description: '',
- },
- {
- key: 'post',
- label: 'POST',
- description: '',
- },
- {
- key: 'patch',
- label: 'PATCH',
- description: '',
- },
- {
- key: 'delete',
- label: 'DELETE',
- description: '',
- },
- ],
- },
- },
- // function_edge_logs
- ...(IS_PLATFORM
- ? {
- function_edge_logs: {
- status_code: {
- label: 'Status',
- key: 'status_code',
- options: [
- {
- key: 'error',
- label: 'Error',
- description: '500 error codes',
- },
- {
- key: 'success',
- label: 'Success',
- description: '200 codes',
- },
- {
- key: 'warning',
- label: 'Warning',
- description: '400 codes',
- },
- ],
- },
- },
- }
- : {}),
- // function_logs
- function_logs: {
- severity: {
- label: 'Severity',
- key: 'severity',
- options: [
- {
- key: 'error',
- label: 'Error',
- description: 'Show all events that are "error" severity',
- },
- {
- key: 'warn',
- label: 'Warning',
- description: 'Show all events that are "warn" severity',
- },
- {
- key: 'info',
- label: 'Info',
- description: 'Show all events that are "info" severity',
- },
- {
- key: 'debug',
- label: 'Debug',
- description: 'Show all events that are "debug" severity',
- },
- {
- key: 'log',
- label: 'Log',
- description: 'Show all events that are "log" severity',
- },
- ],
- },
- },
- // auth logs
- auth_logs: {
- severity: {
- label: 'Severity',
- key: 'severity',
- options: [
- {
- key: 'error',
- label: 'Error',
- description: 'Show all events that have error or fatal severity',
- },
- {
- key: 'warning',
- label: 'Warning',
- description: 'Show all events that have warning severity',
- },
- {
- key: 'info',
- label: 'Info',
- description: 'Show all events that have info severity',
- },
- ],
- },
- status_code: {
- label: 'Status Code',
- key: 'status_code',
- options: [
- {
- key: 'server_error',
- label: 'Server Error',
- description: 'Show all requests with 5XX status code',
- },
- {
- key: 'client_error',
- label: 'Client Error',
- description: 'Show all requests with 4XX status code',
- },
- {
- key: 'redirection',
- label: 'Redirection',
- description: 'Show all requests that have 3XX status code',
- },
- {
- key: 'success',
- label: 'Success',
- description: 'Show all requests that have 2XX status code',
- },
- ],
- },
- endpoints: {
- label: 'Endpoints',
- key: 'endpoints',
- options: [
- {
- key: 'admin',
- label: 'Admin',
- description: 'Show all admin requests',
- },
- {
- key: 'signup',
- label: 'Sign up',
- description: 'Show all signup and authorization requests',
- },
- {
- key: 'recover',
- label: 'Password Recovery',
- description: 'Show all password recovery requests',
- },
- {
- key: 'authentication',
- label: 'Authentication',
- description: 'Show all authentication flow requests (login, otp, and Oauth2)',
- },
- {
- key: 'user',
- label: 'User',
- description: 'Show all user data requests',
- },
- {
- key: 'logout',
- label: 'Logout',
- description: 'Show all logout requests',
- },
- ],
- },
- },
- }
- export const LOGS_TAILWIND_CLASSES = {
- log_selection_x_padding: 'px-8',
- space_y: 'px-6',
- }
- export const PREVIEWER_DATEPICKER_HELPERS: DatetimeHelper[] = [
- {
- text: 'Last 15 minutes',
- calcFrom: () => dayjs().subtract(15, 'minute').toISOString(),
- calcTo: () => '',
- },
- {
- text: 'Last 30 minutes',
- calcFrom: () => dayjs().subtract(30, 'minute').toISOString(),
- calcTo: () => '',
- },
- {
- text: 'Last hour',
- calcFrom: () => dayjs().subtract(1, 'hour').toISOString(),
- calcTo: () => '',
- default: true,
- },
- {
- text: 'Last 3 hours',
- calcFrom: () => dayjs().subtract(3, 'hour').toISOString(),
- calcTo: () => '',
- },
- {
- text: 'Last 24 hours',
- calcFrom: () => dayjs().subtract(1, 'day').toISOString(),
- calcTo: () => '',
- },
- {
- text: 'Last 2 days',
- calcFrom: () => dayjs().subtract(2, 'day').toISOString(),
- calcTo: () => '',
- },
- {
- text: 'Last 3 days',
- calcFrom: () => dayjs().subtract(3, 'day').toISOString(),
- calcTo: () => '',
- },
- {
- text: 'Last 5 days',
- calcFrom: () => dayjs().subtract(5, 'day').toISOString(),
- calcTo: () => '',
- },
- ]
- export const EXPLORER_DATEPICKER_HELPERS: DatetimeHelper[] = [
- {
- text: 'Last hour',
- calcFrom: () => dayjs().subtract(1, 'hour').toISOString(),
- calcTo: () => '',
- default: true,
- },
- {
- text: 'Last 3 hours',
- calcFrom: () => dayjs().subtract(3, 'hour').toISOString(),
- calcTo: () => '',
- },
- {
- text: 'Last 24 hours',
- calcFrom: () => dayjs().subtract(1, 'day').toISOString(),
- calcTo: () => '',
- },
- {
- text: 'Last 3 days',
- calcFrom: () => dayjs().subtract(3, 'day').toISOString(),
- calcTo: () => '',
- },
- {
- text: 'Last 7 days',
- calcFrom: () => dayjs().subtract(7, 'day').toISOString(),
- calcTo: () => '',
- },
- ]
- export const getDefaultHelper = (helpers: DatetimeHelper[]) =>
- helpers.find((helper) => helper.default) || helpers[0]
- export const TIER_QUERY_LIMITS: {
- [x: string]: { text: string; value: 1 | 7 | 28 | 90; unit: 'day'; promptUpgrade: boolean }
- } = {
- FREE: { text: '1 day', value: 1, unit: 'day', promptUpgrade: true },
- PRO: { text: '7 days', value: 7, unit: 'day', promptUpgrade: true },
- PAYG: { text: '7 days', value: 7, unit: 'day', promptUpgrade: true },
- TEAM: { text: '28 days', value: 28, unit: 'day', promptUpgrade: true },
- ENTERPRISE: { text: '90 days', value: 90, unit: 'day', promptUpgrade: false },
- PLATFORM: { text: '1 day', value: 1, unit: 'day', promptUpgrade: false },
- }
- export const LOG_ROUTES_WITH_REPLICA_SUPPORT = [
- '/project/[ref]/logs/edge-logs',
- '/project/[ref]/logs/pooler-logs',
- '/project/[ref]/logs/postgres-logs',
- '/project/[ref]/logs/postgrest-logs',
- ]
|