Logs.constants.ts 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788
  1. import { IS_PLATFORM } from 'common'
  2. import dayjs from 'dayjs'
  3. import type { DatetimeHelper, FilterTableSet, LogTemplate } from './Logs.types'
  4. import { DOCS_URL } from '@/lib/constants'
  5. export const LOGS_EXPLORER_DOCS_URL = `${DOCS_URL}/guides/platform/logs#querying-with-the-logs-explorer`
  6. export const LOGS_LARGE_DATE_RANGE_DAYS_THRESHOLD = 2 // IN DAYS
  7. export const TEMPLATES: LogTemplate[] = [
  8. {
  9. label: 'Recent Errors',
  10. mode: 'simple',
  11. searchString: '[Ee]rror|\\s[45][0-9][0-9]\\s',
  12. for: ['api'],
  13. },
  14. {
  15. label: 'Commits',
  16. mode: 'simple',
  17. searchString: 'COMMIT',
  18. for: ['database'],
  19. },
  20. {
  21. label: 'Commits By User',
  22. description: 'Count of commits made by users on the database',
  23. mode: 'custom',
  24. searchString: `select
  25. p.user_name,
  26. count(*) as count
  27. from postgres_logs
  28. left join unnest(metadata) as m on true
  29. left join unnest(m.parsed) as p on true
  30. where
  31. regexp_contains(event_message, 'COMMIT')
  32. group by
  33. p.user_name
  34. `,
  35. for: ['database'],
  36. },
  37. {
  38. label: 'Metadata IP',
  39. description: 'List all IP addresses that used the Briven API',
  40. mode: 'custom',
  41. searchString: `select
  42. cast(timestamp as datetime) as timestamp,
  43. h.x_real_ip
  44. from edge_logs
  45. left join unnest(metadata) as m on true
  46. left join unnest(m.request) as r on true
  47. left join unnest(r.headers) as h on true
  48. where h.x_real_ip is not null
  49. `,
  50. for: ['api'],
  51. },
  52. {
  53. label: 'Requests by Geography',
  54. description: 'List all ISO 3166-1 alpha-2 country codes that used the Briven API',
  55. mode: 'custom',
  56. searchString: `select
  57. cf.country,
  58. count(*) as count
  59. from edge_logs
  60. left join unnest(metadata) as m on true
  61. left join unnest(m.request) as r on true
  62. left join unnest(r.cf) as cf on true
  63. group by
  64. cf.country
  65. order by
  66. count desc
  67. `,
  68. for: ['api'],
  69. },
  70. {
  71. label: 'Slow Response Time',
  72. mode: 'custom',
  73. description: 'List all Briven API requests that are slow',
  74. searchString: `select
  75. cast(timestamp as datetime) as timestamp,
  76. event_message,
  77. r.origin_time
  78. from edge_logs
  79. cross join unnest(metadata) as m
  80. cross join unnest(m.response) as r
  81. where
  82. r.origin_time > 1000
  83. order by
  84. timestamp desc
  85. limit 100
  86. `,
  87. for: ['api'],
  88. },
  89. {
  90. label: '500 Request Codes',
  91. description: 'List all Briven API requests that responded witha 5XX status code',
  92. mode: 'custom',
  93. searchString: `select
  94. cast(timestamp as datetime) as timestamp,
  95. event_message,
  96. r.status_code
  97. from edge_logs
  98. cross join unnest(metadata) as m
  99. cross join unnest(m.response) as r
  100. where
  101. r.status_code >= 500
  102. order by
  103. timestamp desc
  104. limit 100
  105. `,
  106. for: ['api'],
  107. },
  108. {
  109. label: 'Top Paths',
  110. description: 'List the most requested Briven API paths',
  111. mode: 'custom',
  112. searchString: `select
  113. r.path as path,
  114. r.search as params,
  115. count(timestamp) as c
  116. from edge_logs
  117. cross join unnest(metadata) as m
  118. cross join unnest(m.request) as r
  119. group by
  120. path,
  121. params
  122. order by
  123. c desc
  124. limit 100
  125. `,
  126. for: ['api'],
  127. },
  128. {
  129. label: 'REST Requests',
  130. description: 'List all PostgREST requests',
  131. mode: 'custom',
  132. searchString: `select
  133. cast(timestamp as datetime) as timestamp,
  134. event_message
  135. from edge_logs
  136. cross join unnest(metadata) as m
  137. cross join unnest(m.request) as r
  138. where
  139. path like '%rest/v1%'
  140. order by
  141. timestamp desc
  142. limit 100
  143. `,
  144. for: ['api'],
  145. },
  146. {
  147. label: 'Errors',
  148. description: 'List all Postgres error messages with ERROR, FATAL, or PANIC severity',
  149. mode: 'custom',
  150. searchString: `select
  151. cast(t.timestamp as datetime) as timestamp,
  152. p.error_severity,
  153. event_message
  154. from postgres_logs as t
  155. cross join unnest(metadata) as m
  156. cross join unnest(m.parsed) as p
  157. where
  158. p.error_severity in ('ERROR', 'FATAL', 'PANIC')
  159. order by
  160. timestamp desc
  161. limit 100
  162. `,
  163. for: ['database'],
  164. },
  165. {
  166. label: 'Error Count by User',
  167. description: 'Count of errors by users',
  168. mode: 'custom',
  169. searchString: `select
  170. count(t.timestamp) as count,
  171. p.user_name,
  172. p.error_severity
  173. from postgres_logs as t
  174. cross join unnest(metadata) as m
  175. cross join unnest(m.parsed) as p
  176. where
  177. p.error_severity in ('ERROR', 'FATAL', 'PANIC')
  178. group by
  179. p.user_name,
  180. p.error_severity
  181. order by
  182. count desc
  183. limit 100
  184. `,
  185. for: ['database'],
  186. },
  187. {
  188. label: 'Auth Endpoint Events',
  189. description: 'Endpoint events filtered by path',
  190. mode: 'custom',
  191. searchString: `select
  192. t.timestamp,
  193. event_message
  194. from auth_logs as t
  195. where
  196. regexp_contains(event_message,"level.{3}(info|warning||error|fatal)")
  197. -- and regexp_contains(event_message,"path.{3}(/token|/recover|/signup|/otp)")
  198. limit 100
  199. `,
  200. for: ['database'],
  201. },
  202. {
  203. label: 'Auth Audit Logs',
  204. description: 'Audit logs for auth events',
  205. mode: 'custom',
  206. searchString: `select
  207. cast(timestamp as datetime) as timestamp,
  208. event_message, metadata
  209. from auth_audit_logs
  210. limit 10
  211. `,
  212. for: ['database'],
  213. },
  214. {
  215. label: 'Storage Object Requests',
  216. description: 'Number of requests done on Storage Objects',
  217. mode: 'custom',
  218. searchString: `select
  219. r.method as http_verb,
  220. r.path as filepath,
  221. count(*) as num_requests
  222. from edge_logs
  223. cross join unnest(metadata) as m
  224. cross join unnest(m.request) AS r
  225. cross join unnest(r.headers) AS h
  226. where
  227. path like '%storage/v1/object/%'
  228. group by
  229. r.path, r.method
  230. order by
  231. num_requests desc
  232. limit 100
  233. `,
  234. for: ['api'],
  235. },
  236. {
  237. label: 'Storage Egress Requests',
  238. description: 'Check the number of requests done on Storage Affecting Egress',
  239. mode: 'custom',
  240. searchString: `select
  241. request.method as http_verb,
  242. request.path as filepath,
  243. (responseHeaders.cf_cache_status = 'HIT') as cached,
  244. count(*) as num_requests
  245. from
  246. edge_logs
  247. cross join unnest(metadata) as metadata
  248. cross join unnest(metadata.request) as request
  249. cross join unnest(metadata.response) as response
  250. cross join unnest(response.headers) as responseHeaders
  251. where
  252. (path like '%storage/v1/object/%' or path like '%storage/v1/render/%')
  253. and request.method = 'GET'
  254. group by 1, 2, 3
  255. order by num_requests desc
  256. limit 100;
  257. `,
  258. for: ['api'],
  259. },
  260. {
  261. label: 'Storage Top Cache Misses',
  262. description: 'The top Storage requests that miss caching',
  263. mode: 'custom',
  264. searchString: `select
  265. r.path as path,
  266. r.search as search,
  267. count(id) as count
  268. from edge_logs f
  269. cross join unnest(f.metadata) as m
  270. cross join unnest(m.request) as r
  271. cross join unnest(m.response) as res
  272. cross join unnest(res.headers) as h
  273. where starts_with(r.path, '/storage/v1/object')
  274. and r.method = 'GET'
  275. and h.cf_cache_status in ('MISS', 'NONE/UNKNOWN', 'EXPIRED', 'BYPASS', 'DYNAMIC')
  276. group by path, search
  277. order by count desc
  278. limit 100;
  279. `,
  280. for: ['api'],
  281. },
  282. ]
  283. const _SQL_FILTER_COMMON = {
  284. search_query: (value: string) => `regexp_contains(event_message, '${value}')`,
  285. }
  286. export const SQL_FILTER_TEMPLATES: any = {
  287. postgres_logs: {
  288. ..._SQL_FILTER_COMMON,
  289. database: (value: string) => `identifier = '${value}'`,
  290. 'severity.error': `parsed.error_severity in ('ERROR', 'FATAL', 'PANIC')`,
  291. 'severity.noError': `parsed.error_severity not in ('ERROR', 'FATAL', 'PANIC')`,
  292. 'severity.log': `parsed.error_severity = 'LOG'`,
  293. },
  294. edge_logs: {
  295. ..._SQL_FILTER_COMMON,
  296. database: (value: string) => `identifier = '${value}'`,
  297. 'status_code.error': `response.status_code between 500 and 599`,
  298. 'status_code.success': `response.status_code between 200 and 299`,
  299. 'status_code.warning': `response.status_code between 400 and 499`,
  300. 'product.database': `request.path like '/rest/%' or request.path like '/graphql/%'`,
  301. 'product.storage': `request.path like '/storage/%'`,
  302. 'product.auth': `request.path like '/auth/%'`,
  303. 'product.realtime': `request.path like '/realtime/%'`,
  304. 'method.get': `request.method = 'GET'`,
  305. 'method.post': `request.method = 'POST'`,
  306. 'method.put': `request.method = 'PUT'`,
  307. 'method.patch': `request.method = 'PATCH'`,
  308. 'method.delete': `request.method = 'DELETE'`,
  309. 'method.options': `request.method = 'OPTIONS'`,
  310. },
  311. function_edge_logs: {
  312. ..._SQL_FILTER_COMMON,
  313. 'status_code.error': `response.status_code between 500 and 599`,
  314. 'status_code.success': `response.status_code between 200 and 299`,
  315. 'status_code.warning': `response.status_code between 400 and 499`,
  316. },
  317. function_logs: {
  318. ..._SQL_FILTER_COMMON,
  319. 'severity.error': `metadata.level = 'error'`,
  320. 'severity.notError': `metadata.level != 'error'`,
  321. 'severity.log': `metadata.level = 'log'`,
  322. 'severity.info': `metadata.level = 'info'`,
  323. 'severity.debug': `metadata.level = 'debug'`,
  324. 'severity.warn': `metadata.level = 'warn'`,
  325. },
  326. auth_logs: {
  327. ..._SQL_FILTER_COMMON,
  328. 'severity.error': `metadata.level = 'error' or metadata.level = 'fatal'`,
  329. 'severity.warning': `metadata.level = 'warning'`,
  330. 'severity.info': `metadata.level = 'info'`,
  331. 'status_code.server_error': `cast(metadata.status as int64) between 500 and 599`,
  332. 'status_code.client_error': `cast(metadata.status as int64) between 400 and 499`,
  333. 'status_code.redirection': `cast(metadata.status as int64) between 300 and 399`,
  334. 'status_code.success': `cast(metadata.status as int64) between 200 and 299`,
  335. 'endpoints.admin': `REGEXP_CONTAINS(metadata.path, "/admin")`,
  336. 'endpoints.signup': `REGEXP_CONTAINS(metadata.path, "/signup|/invite|/verify")`,
  337. 'endpoints.authentication': `REGEXP_CONTAINS(metadata.path, "/token|/authorize|/callback|/otp|/magiclink")`,
  338. 'endpoints.recover': `REGEXP_CONTAINS(metadata.path, "/recover")`,
  339. 'endpoints.user': `REGEXP_CONTAINS(metadata.path, "/user")`,
  340. 'endpoints.logout': `REGEXP_CONTAINS(metadata.path, "/logout")`,
  341. },
  342. realtime_logs: {
  343. ..._SQL_FILTER_COMMON,
  344. },
  345. storage_logs: {
  346. ..._SQL_FILTER_COMMON,
  347. },
  348. postgrest_logs: {
  349. ..._SQL_FILTER_COMMON,
  350. database: (value: string) => `identifier = '${value}'`,
  351. },
  352. pgbouncer_logs: {
  353. ..._SQL_FILTER_COMMON,
  354. },
  355. supavisor_logs: {
  356. ..._SQL_FILTER_COMMON,
  357. database: (value: string) => `m.project like '${value}%'`,
  358. },
  359. pg_upgrade_logs: {
  360. ..._SQL_FILTER_COMMON,
  361. },
  362. pg_cron_logs: {
  363. ..._SQL_FILTER_COMMON,
  364. },
  365. etl_replication_logs: {
  366. ..._SQL_FILTER_COMMON,
  367. pipeline_id: (value: string | number) => `pipeline_id = ${value}`,
  368. },
  369. }
  370. export enum LogsTableName {
  371. EDGE = 'edge_logs',
  372. POSTGRES = 'postgres_logs',
  373. FUNCTIONS = 'function_logs',
  374. FN_EDGE = 'function_edge_logs',
  375. AUTH = 'auth_logs',
  376. AUTH_AUDIT = 'auth_audit_logs',
  377. REALTIME = 'realtime_logs',
  378. STORAGE = 'storage_logs',
  379. POSTGREST = 'postgrest_logs',
  380. SUPAVISOR = 'supavisor_logs',
  381. PGBOUNCER = 'pgbouncer_logs',
  382. PG_UPGRADE = 'pg_upgrade_logs',
  383. PG_CRON = 'pg_cron_logs',
  384. ETL = 'etl_replication_logs',
  385. }
  386. export const LOGS_TABLES = {
  387. api: LogsTableName.EDGE,
  388. database: LogsTableName.POSTGRES,
  389. functions: LogsTableName.FUNCTIONS,
  390. fn_edge: LogsTableName.FN_EDGE,
  391. auth: LogsTableName.AUTH,
  392. realtime: LogsTableName.REALTIME,
  393. storage: LogsTableName.STORAGE,
  394. postgrest: LogsTableName.POSTGREST,
  395. supavisor: LogsTableName.SUPAVISOR,
  396. pg_upgrade: LogsTableName.PG_UPGRADE,
  397. pg_cron: LogsTableName.POSTGRES,
  398. pgbouncer: LogsTableName.PGBOUNCER,
  399. etl: LogsTableName.ETL,
  400. }
  401. export const LOGS_SOURCE_DESCRIPTION = {
  402. [LogsTableName.EDGE]: 'Logs obtained from the network edge, containing all API requests',
  403. [LogsTableName.POSTGRES]: 'Database logs obtained directly from Postgres',
  404. [LogsTableName.FUNCTIONS]: 'Function logs generated from runtime execution',
  405. [LogsTableName.FN_EDGE]: 'Function call logs, containing the request and response',
  406. [LogsTableName.AUTH]: 'Errors, warnings, and performance details from the auth service',
  407. [LogsTableName.AUTH_AUDIT]: 'Audit records of user signups, logins, and account changes',
  408. [LogsTableName.REALTIME]: 'Realtime server for Postgres logical replication broadcasting',
  409. [LogsTableName.STORAGE]: 'Object storage logs',
  410. [LogsTableName.POSTGREST]: 'RESTful API web server logs',
  411. [LogsTableName.SUPAVISOR]: 'Shared connection pooler logs for PostgreSQL',
  412. [LogsTableName.PGBOUNCER]: 'Dedicated connection pooler for PostgreSQL',
  413. [LogsTableName.PG_UPGRADE]: 'Logs generated by the Postgres version upgrade process',
  414. [LogsTableName.PG_CRON]: 'Postgres logs from pg_cron cron jobs',
  415. [LogsTableName.ETL]: 'Logs from the replication process',
  416. }
  417. export const FILTER_OPTIONS: FilterTableSet = {
  418. // Postgres logs
  419. postgres_logs: {
  420. severity: {
  421. label: 'Severity',
  422. key: 'severity',
  423. options: [
  424. {
  425. key: 'error',
  426. label: 'Error',
  427. description: 'Show all events with ERROR, PANIC, or FATAL',
  428. },
  429. {
  430. key: 'noError',
  431. label: 'No Error',
  432. description: 'Show all non-error events',
  433. },
  434. {
  435. key: 'log',
  436. label: 'Log',
  437. description: 'Show all events that are log severity',
  438. },
  439. ],
  440. },
  441. },
  442. // Edge logs
  443. edge_logs: {
  444. status_code: {
  445. label: 'Status',
  446. key: 'status_code',
  447. options: [
  448. {
  449. key: 'error',
  450. label: 'Error',
  451. description: '500 error codes',
  452. },
  453. {
  454. key: 'success',
  455. label: 'Success',
  456. description: '200 codes',
  457. },
  458. {
  459. key: 'warning',
  460. label: 'Warning',
  461. description: '400 codes',
  462. },
  463. ],
  464. },
  465. product: {
  466. label: 'Product',
  467. key: 'product',
  468. options: [
  469. {
  470. key: 'database',
  471. label: 'Database',
  472. description: '',
  473. },
  474. {
  475. key: 'auth',
  476. label: 'Auth',
  477. description: '',
  478. },
  479. {
  480. key: 'storage',
  481. label: 'Storage',
  482. description: '',
  483. },
  484. {
  485. key: 'realtime',
  486. label: 'Realtime',
  487. description: '',
  488. },
  489. ],
  490. },
  491. method: {
  492. label: 'Method',
  493. key: 'method',
  494. options: [
  495. {
  496. key: 'get',
  497. label: 'GET',
  498. description: '',
  499. },
  500. {
  501. key: 'options',
  502. label: 'OPTIONS',
  503. description: '',
  504. },
  505. {
  506. key: 'put',
  507. label: 'PUT',
  508. description: '',
  509. },
  510. {
  511. key: 'post',
  512. label: 'POST',
  513. description: '',
  514. },
  515. {
  516. key: 'patch',
  517. label: 'PATCH',
  518. description: '',
  519. },
  520. {
  521. key: 'delete',
  522. label: 'DELETE',
  523. description: '',
  524. },
  525. ],
  526. },
  527. },
  528. // function_edge_logs
  529. ...(IS_PLATFORM
  530. ? {
  531. function_edge_logs: {
  532. status_code: {
  533. label: 'Status',
  534. key: 'status_code',
  535. options: [
  536. {
  537. key: 'error',
  538. label: 'Error',
  539. description: '500 error codes',
  540. },
  541. {
  542. key: 'success',
  543. label: 'Success',
  544. description: '200 codes',
  545. },
  546. {
  547. key: 'warning',
  548. label: 'Warning',
  549. description: '400 codes',
  550. },
  551. ],
  552. },
  553. },
  554. }
  555. : {}),
  556. // function_logs
  557. function_logs: {
  558. severity: {
  559. label: 'Severity',
  560. key: 'severity',
  561. options: [
  562. {
  563. key: 'error',
  564. label: 'Error',
  565. description: 'Show all events that are "error" severity',
  566. },
  567. {
  568. key: 'warn',
  569. label: 'Warning',
  570. description: 'Show all events that are "warn" severity',
  571. },
  572. {
  573. key: 'info',
  574. label: 'Info',
  575. description: 'Show all events that are "info" severity',
  576. },
  577. {
  578. key: 'debug',
  579. label: 'Debug',
  580. description: 'Show all events that are "debug" severity',
  581. },
  582. {
  583. key: 'log',
  584. label: 'Log',
  585. description: 'Show all events that are "log" severity',
  586. },
  587. ],
  588. },
  589. },
  590. // auth logs
  591. auth_logs: {
  592. severity: {
  593. label: 'Severity',
  594. key: 'severity',
  595. options: [
  596. {
  597. key: 'error',
  598. label: 'Error',
  599. description: 'Show all events that have error or fatal severity',
  600. },
  601. {
  602. key: 'warning',
  603. label: 'Warning',
  604. description: 'Show all events that have warning severity',
  605. },
  606. {
  607. key: 'info',
  608. label: 'Info',
  609. description: 'Show all events that have info severity',
  610. },
  611. ],
  612. },
  613. status_code: {
  614. label: 'Status Code',
  615. key: 'status_code',
  616. options: [
  617. {
  618. key: 'server_error',
  619. label: 'Server Error',
  620. description: 'Show all requests with 5XX status code',
  621. },
  622. {
  623. key: 'client_error',
  624. label: 'Client Error',
  625. description: 'Show all requests with 4XX status code',
  626. },
  627. {
  628. key: 'redirection',
  629. label: 'Redirection',
  630. description: 'Show all requests that have 3XX status code',
  631. },
  632. {
  633. key: 'success',
  634. label: 'Success',
  635. description: 'Show all requests that have 2XX status code',
  636. },
  637. ],
  638. },
  639. endpoints: {
  640. label: 'Endpoints',
  641. key: 'endpoints',
  642. options: [
  643. {
  644. key: 'admin',
  645. label: 'Admin',
  646. description: 'Show all admin requests',
  647. },
  648. {
  649. key: 'signup',
  650. label: 'Sign up',
  651. description: 'Show all signup and authorization requests',
  652. },
  653. {
  654. key: 'recover',
  655. label: 'Password Recovery',
  656. description: 'Show all password recovery requests',
  657. },
  658. {
  659. key: 'authentication',
  660. label: 'Authentication',
  661. description: 'Show all authentication flow requests (login, otp, and Oauth2)',
  662. },
  663. {
  664. key: 'user',
  665. label: 'User',
  666. description: 'Show all user data requests',
  667. },
  668. {
  669. key: 'logout',
  670. label: 'Logout',
  671. description: 'Show all logout requests',
  672. },
  673. ],
  674. },
  675. },
  676. }
  677. export const LOGS_TAILWIND_CLASSES = {
  678. log_selection_x_padding: 'px-8',
  679. space_y: 'px-6',
  680. }
  681. export const PREVIEWER_DATEPICKER_HELPERS: DatetimeHelper[] = [
  682. {
  683. text: 'Last 15 minutes',
  684. calcFrom: () => dayjs().subtract(15, 'minute').toISOString(),
  685. calcTo: () => '',
  686. },
  687. {
  688. text: 'Last 30 minutes',
  689. calcFrom: () => dayjs().subtract(30, 'minute').toISOString(),
  690. calcTo: () => '',
  691. },
  692. {
  693. text: 'Last hour',
  694. calcFrom: () => dayjs().subtract(1, 'hour').toISOString(),
  695. calcTo: () => '',
  696. default: true,
  697. },
  698. {
  699. text: 'Last 3 hours',
  700. calcFrom: () => dayjs().subtract(3, 'hour').toISOString(),
  701. calcTo: () => '',
  702. },
  703. {
  704. text: 'Last 24 hours',
  705. calcFrom: () => dayjs().subtract(1, 'day').toISOString(),
  706. calcTo: () => '',
  707. },
  708. {
  709. text: 'Last 2 days',
  710. calcFrom: () => dayjs().subtract(2, 'day').toISOString(),
  711. calcTo: () => '',
  712. },
  713. {
  714. text: 'Last 3 days',
  715. calcFrom: () => dayjs().subtract(3, 'day').toISOString(),
  716. calcTo: () => '',
  717. },
  718. {
  719. text: 'Last 5 days',
  720. calcFrom: () => dayjs().subtract(5, 'day').toISOString(),
  721. calcTo: () => '',
  722. },
  723. ]
  724. export const EXPLORER_DATEPICKER_HELPERS: DatetimeHelper[] = [
  725. {
  726. text: 'Last hour',
  727. calcFrom: () => dayjs().subtract(1, 'hour').toISOString(),
  728. calcTo: () => '',
  729. default: true,
  730. },
  731. {
  732. text: 'Last 3 hours',
  733. calcFrom: () => dayjs().subtract(3, 'hour').toISOString(),
  734. calcTo: () => '',
  735. },
  736. {
  737. text: 'Last 24 hours',
  738. calcFrom: () => dayjs().subtract(1, 'day').toISOString(),
  739. calcTo: () => '',
  740. },
  741. {
  742. text: 'Last 3 days',
  743. calcFrom: () => dayjs().subtract(3, 'day').toISOString(),
  744. calcTo: () => '',
  745. },
  746. {
  747. text: 'Last 7 days',
  748. calcFrom: () => dayjs().subtract(7, 'day').toISOString(),
  749. calcTo: () => '',
  750. },
  751. ]
  752. export const getDefaultHelper = (helpers: DatetimeHelper[]) =>
  753. helpers.find((helper) => helper.default) || helpers[0]
  754. export const TIER_QUERY_LIMITS: {
  755. [x: string]: { text: string; value: 1 | 7 | 28 | 90; unit: 'day'; promptUpgrade: boolean }
  756. } = {
  757. FREE: { text: '1 day', value: 1, unit: 'day', promptUpgrade: true },
  758. PRO: { text: '7 days', value: 7, unit: 'day', promptUpgrade: true },
  759. PAYG: { text: '7 days', value: 7, unit: 'day', promptUpgrade: true },
  760. TEAM: { text: '28 days', value: 28, unit: 'day', promptUpgrade: true },
  761. ENTERPRISE: { text: '90 days', value: 90, unit: 'day', promptUpgrade: false },
  762. PLATFORM: { text: '1 day', value: 1, unit: 'day', promptUpgrade: false },
  763. }
  764. export const LOG_ROUTES_WITH_REPLICA_SUPPORT = [
  765. '/project/[ref]/logs/edge-logs',
  766. '/project/[ref]/logs/pooler-logs',
  767. '/project/[ref]/logs/postgres-logs',
  768. '/project/[ref]/logs/postgrest-logs',
  769. ]