| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394 |
- /**
- * Service Flow SQL Queries
- *
- * This file contains SQL queries for fetching enriched service flow data
- * showing how requests flow through different layers of the infrastructure.
- */
- // Service configuration for different log types
- const SERVICE_CONFIGS = {
- postgrest: {
- pathFilter: '%/rest/%',
- },
- auth: {
- pathFilter: '%/auth/%',
- },
- 'edge-function': {
- pathFilter: '%/functions/%',
- },
- storage: {
- pathFilter: '%/storage/%',
- },
- } as const
- type EdgeServiceType = keyof typeof SERVICE_CONFIGS
- /**
- * Base Edge Logs Service Flow Query
- * Consolidated query for all edge-based services (postgrest, auth, edge-function, storage)
- * to eliminate 500+ lines of SQL duplication
- */
- const getBaseEdgeServiceFlowQuery = (logId: string, serviceType: EdgeServiceType): string => {
- return `
- select
- id,
- el.timestamp as timestamp,
- '${serviceType}' as log_type,
- CAST(edge_logs_response.status_code AS STRING) as status,
- CASE
- WHEN edge_logs_response.status_code BETWEEN 200 AND 299 THEN 'success'
- WHEN edge_logs_response.status_code BETWEEN 400 AND 499 THEN 'warning'
- WHEN edge_logs_response.status_code >= 500 THEN 'error'
- ELSE 'success'
- END as level,
-
- -- Request data
- edge_logs_request.path as request_path,
- edge_logs_request.host as request_host,
- edge_logs_request.method as request_method,
- edge_logs_request.url as request_url,
- edge_logs_request.search as request_search,
-
- -- Response data
- edge_logs_response.origin_time as response_origin_time,
- edge_logs_response_headers.content_type as response_content_type,
- edge_logs_response_headers.cf_cache_status as response_cache_status,
-
- -- Client location data
- edge_logs_cf.continent as client_continent,
- edge_logs_cf.country as client_country,
- edge_logs_cf.city as client_city,
- edge_logs_cf.region as client_region,
- edge_logs_cf.regionCode as client_region_code,
- edge_logs_cf.latitude as client_latitude,
- edge_logs_cf.longitude as client_longitude,
- edge_logs_cf.timezone as client_timezone,
-
- -- Network data
- edge_logs_cf.httpProtocol as network_protocol,
- edge_logs_cf.colo as network_datacenter,
-
- -- Request headers
- edge_logs_request_headers.user_agent as headers_user_agent,
- edge_logs_request_headers.x_client_info as headers_x_client_info,
- edge_logs_request_headers.x_forwarded_proto as headers_x_forwarded_proto,
- edge_logs_request_headers.x_real_ip as headers_x_real_ip,
- edge_logs_request_headers.referer as headers_referer,
-
- -- Auth data
- authorization_payload.role as api_role,
- COALESCE(sb.auth_user, null) as auth_user,
-
- -- JWT Key Authentication (old keys)
- CASE
- WHEN apikey_payload.algorithm = 'HS256' AND
- apikey_payload.issuer = 'briven' AND
- apikey_payload.role IN ('anon', 'service_role')
- THEN apikey_payload.role
- WHEN apikey_payload IS NOT NULL THEN '<unrecognized>'
- ELSE NULL
- END as jwt_key_role,
-
- apikey_payload.signature_prefix as jwt_key_prefix,
-
- -- API Key Authentication (new keys from sb.apikey[0].apikey[0])
- CASE
- WHEN sb_apikey_inner.prefix LIKE '%publishable%' THEN 'anon'
- WHEN sb_apikey_inner.prefix LIKE '%secret%' THEN 'service_role'
- WHEN sb_apikey_inner.prefix IS NOT NULL THEN 'unknown'
- ELSE NULL
- END as api_key_role,
-
- sb_apikey_inner.prefix as api_key_prefix,
- sb_apikey_inner.error as api_key_error,
- sb_apikey_inner.hash as api_key_hash,
-
- -- User Authorization
- authorization_payload.role as authorization_role,
- null as user_id,
- null as user_email,
-
- -- Cloudflare Network Info
- edge_logs_response_headers.cf_ray as cf_ray,
- edge_logs_request_headers.cf_ipcountry as cf_country,
- edge_logs_cf.colo as cf_datacenter,
- edge_logs_request_headers.cf_connecting_ip as client_ip,
-
- -- JWT data
- apikey_payload.role as jwt_apikey_role,
- apikey_payload.algorithm as jwt_apikey_algorithm,
- apikey_payload.expires_at as jwt_apikey_expires_at,
- apikey_payload.issuer as jwt_apikey_issuer,
- apikey_payload.signature_prefix as jwt_apikey_signature_prefix,
- null as jwt_apikey_key_id,
- null as jwt_apikey_session_id,
- apikey_payload.subject as jwt_apikey_subject,
-
- authorization_payload.role as jwt_auth_role,
- authorization_payload.algorithm as jwt_auth_algorithm,
- authorization_payload.expires_at as jwt_auth_expires_at,
- authorization_payload.issuer as jwt_auth_issuer,
- authorization_payload.signature_prefix as jwt_auth_signature_prefix,
- authorization_payload.key_id as jwt_auth_key_id,
- authorization_payload.session_id as jwt_auth_session_id,
- authorization_payload.subject as jwt_auth_subject,
-
- -- Storage specific data (included for all but only populated for storage)
- edge_logs_response_headers.sb_gateway_mode as storage_edge_gateway_mode,
- edge_logs_response_headers.sb_gateway_version as storage_edge_gateway_version,
- edge_logs_response_headers.cf_ray as correlation_cf_ray,
-
- -- Raw data
- el as raw_log_data
-
- from edge_logs as el
- cross join unnest(metadata) as edge_logs_metadata
- cross join unnest(edge_logs_metadata.request) as edge_logs_request
- cross join unnest(edge_logs_metadata.response) as edge_logs_response
- left join unnest(edge_logs_response.headers) as edge_logs_response_headers
- left join unnest(edge_logs_request.headers) as edge_logs_request_headers
- left join unnest(edge_logs_request.cf) as edge_logs_cf
- left join unnest(edge_logs_request.sb) as sb
- left join unnest(sb.jwt) as jwt
- left join unnest(COALESCE(jwt.apikey, [])) as apikey
- left join unnest(COALESCE(apikey.payload, [])) as apikey_payload
- left join unnest(COALESCE(jwt.authorization, [])) as auth
- left join unnest(COALESCE(auth.payload, [])) as authorization_payload
- left join unnest(COALESCE(sb.apikey, [])) as sb_apikey_outer
- left join unnest(COALESCE(sb_apikey_outer.apikey, [])) as sb_apikey_inner
- WHERE
- el.id = '${logId}'
- `
- }
- /**
- * PostgREST Service Flow Query for /rest/ requests
- * Fetches enriched edge log data for PostgREST requests with additional service-specific metadata
- */
- export const getPostgrestServiceFlowQuery = (logId: string): string => {
- return getBaseEdgeServiceFlowQuery(logId, 'postgrest')
- }
- /**
- * Auth Service Flow Query for /auth/ requests
- * Fetches enriched edge log data for GoTrue auth requests with service-specific metadata
- */
- export const getAuthServiceFlowQuery = (logId: string): string => {
- return getBaseEdgeServiceFlowQuery(logId, 'auth')
- }
- /**
- * Edge Function Service Flow Query for /functions/ requests
- * Fetches enriched edge log data for Edge Function requests with service-specific metadata
- * NOTE: Uses function_edge_logs table instead of edge_logs, so kept separate like postgres
- */
- export const getEdgeFunctionServiceFlowQuery = (logId: string): string => {
- return `
- select
- fel.id as id,
- fel.timestamp as timestamp,
- 'edge-function' as log_type,
- CAST(fel_response.status_code AS STRING) as status,
- CASE
- WHEN fel_response.status_code BETWEEN 200 AND 299 THEN 'success'
- WHEN fel_response.status_code BETWEEN 400 AND 499 THEN 'warning'
- WHEN fel_response.status_code >= 500 THEN 'error'
- ELSE 'success'
- END as level,
-
- -- Request data
- fel_request.pathname as request_path,
- fel_request.host as request_host,
- fel_request.method as request_method,
- fel_request.url as request_url,
- fel_request.search as request_search,
- fel_request.protocol as request_protocol,
- fel_request.port as request_port,
-
- -- Response data (no origin_time in function_edge_logs)
- fel_response_headers.content_type as response_content_type,
- fel_response_headers.content_length as response_content_length,
- fel_response_headers.date as response_date,
- fel_response_headers.server as response_server,
- fel_response_headers.x_sb_edge_region as response_edge_region,
- fel_response_headers.x_sb_compute_multiplier as response_compute_multiplier,
- fel_response_headers.x_sb_resource_multiplier as response_resource_multiplier,
- fel_response_headers.x_served_by as response_served_by,
-
- -- Function specific data
- fel_metadata.execution_id as execution_id,
- fel_metadata.function_id as function_id,
- fel_metadata.deployment_id as deployment_id,
- fel_metadata.execution_time_ms as execution_time_ms,
- fel_metadata.project_ref as project_ref,
- fel_metadata.version as function_version,
-
- -- Request headers
- fel_request_headers.user_agent as headers_user_agent,
- fel_request_headers.x_client_info as headers_x_client_info,
- fel_request_headers.accept as headers_accept,
- fel_request_headers.accept_encoding as headers_accept_encoding,
- fel_request_headers.connection as headers_connection,
- fel_request_headers.cookie as headers_cookie,
- fel_request_headers.host as headers_host,
-
- -- Auth data
- authorization_payload.role as api_role,
- COALESCE(sb.auth_user, null) as auth_user,
-
- -- JWT Key Authentication (old keys)
- CASE
- WHEN apikey_payload.algorithm = 'HS256' AND
- apikey_payload.issuer = 'briven' AND
- apikey_payload.role IN ('anon', 'service_role')
- THEN apikey_payload.role
- WHEN apikey_payload IS NOT NULL THEN '<unrecognized>'
- ELSE NULL
- END as jwt_key_role,
-
- apikey_payload.signature_prefix as jwt_key_prefix,
-
- -- API Key Authentication (new keys from sb.apikey[0].apikey[0])
- CASE
- WHEN sb_apikey_inner.prefix LIKE '%publishable%' THEN 'anon'
- WHEN sb_apikey_inner.prefix LIKE '%secret%' THEN 'service_role'
- WHEN sb_apikey_inner.prefix IS NOT NULL THEN 'unknown'
- ELSE NULL
- END as api_key_role,
-
- sb_apikey_inner.prefix as api_key_prefix,
- sb_apikey_inner.error as api_key_error,
- sb_apikey_inner.hash as api_key_hash,
-
- -- User Authorization
- authorization_payload.role as authorization_role,
- null as user_id,
- null as user_email,
-
- -- JWT data
- apikey_payload.role as jwt_apikey_role,
- apikey_payload.algorithm as jwt_apikey_algorithm,
- apikey_payload.expires_at as jwt_apikey_expires_at,
- apikey_payload.issuer as jwt_apikey_issuer,
- apikey_payload.signature_prefix as jwt_apikey_signature_prefix,
- null as jwt_apikey_key_id,
- null as jwt_apikey_session_id,
- apikey_payload.subject as jwt_apikey_subject,
-
- authorization_payload.role as jwt_auth_role,
- authorization_payload.algorithm as jwt_auth_algorithm,
- authorization_payload.expires_at as jwt_auth_expires_at,
- authorization_payload.issuer as jwt_auth_issuer,
- authorization_payload.signature_prefix as jwt_auth_signature_prefix,
- authorization_payload.key_id as jwt_auth_key_id,
- authorization_payload.session_id as jwt_auth_session_id,
- authorization_payload.subject as jwt_auth_subject,
-
- -- Function logs aggregation
- function_logs_agg.function_log_count as function_log_count,
- function_logs_agg.logs as function_logs,
- function_logs_agg.last_event_message as last_event_message,
-
- -- Raw data
- fel as raw_log_data
-
- from function_edge_logs as fel
- cross join unnest(metadata) as fel_metadata
- cross join unnest(fel_metadata.response) as fel_response
- cross join unnest(fel_metadata.request) as fel_request
- left join unnest(fel_response.headers) as fel_response_headers
- left join unnest(fel_request.headers) as fel_request_headers
- left join unnest(fel_request.sb) as sb
- left join unnest(sb.jwt) as jwt
- left join unnest(COALESCE(jwt.apikey, [])) as apikey
- left join unnest(COALESCE(apikey.payload, [])) as apikey_payload
- left join unnest(COALESCE(jwt.authorization, [])) as auth
- left join unnest(COALESCE(auth.payload, [])) as authorization_payload
- left join unnest(COALESCE(sb.apikey, [])) as sb_apikey_outer
- left join unnest(COALESCE(sb_apikey_outer.apikey, [])) as sb_apikey_inner
- left join (
- SELECT
- fl_metadata.execution_id,
- COUNT(fl.id) as function_log_count,
- ANY_VALUE(fl.event_message) as last_event_message,
- ARRAY_AGG(STRUCT(fl.id, fl.timestamp, fl.event_message, fl_metadata.level, fl_metadata.event_type)) as logs
- FROM function_logs as fl
- CROSS JOIN UNNEST(fl.metadata) as fl_metadata
- WHERE fl_metadata.execution_id IS NOT NULL
- GROUP BY fl_metadata.execution_id
- ) as function_logs_agg on fel_metadata.execution_id = function_logs_agg.execution_id
- WHERE
- fel.id = '${logId}'
- `
- }
- /**
- * Storage Service Flow Query for /storage/ requests
- * Fetches enriched edge log data for Storage requests with service-specific metadata
- */
- export const getStorageServiceFlowQuery = (logId: string): string => {
- return getBaseEdgeServiceFlowQuery(logId, 'storage')
- }
- /**
- * Postgres Service Flow Query for database operations
- * Fetches enriched postgres log data with database-specific metadata
- *
- * This handles direct database operations, connections, and queries
- * NOTE: Uses postgres_logs table instead of edge_logs, so kept separate
- */
- export const getPostgresServiceFlowQuery = (logId: string): string => {
- return `
- select
- pgl.id as id,
- pgl.timestamp as timestamp,
- 'postgres' as log_type,
- pgl_parsed.sql_state_code as status,
- CASE
- WHEN pgl_parsed.error_severity = 'LOG' THEN 'success'
- WHEN pgl_parsed.error_severity = 'WARNING' THEN 'warning'
- WHEN pgl_parsed.error_severity = 'FATAL' THEN 'error'
- WHEN pgl_parsed.error_severity = 'ERROR' THEN 'error'
- ELSE 'success'
- END as level,
-
- -- Database connection details
- pgl_parsed.database_name as database_name,
- pgl_parsed.user_name as database_user,
- pgl_parsed.connection_from as connection_from,
- pgl_metadata.host as database_host,
-
- -- Query/Operation details
- pgl_parsed.command_tag as command_tag,
- pgl_parsed.backend_type as backend_type,
- pgl_parsed.query_id as query_id,
-
- -- Session details
- pgl_parsed.session_id as session_id,
- pgl_parsed.process_id as process_id,
- pgl_parsed.virtual_transaction_id as virtual_transaction_id,
- pgl_parsed.transaction_id as transaction_id,
- pgl_parsed.session_start_time as session_start_time,
- pgl_parsed.session_line_num as session_line_num,
-
- -- Error/Status details
- pgl_parsed.error_severity as error_severity,
- pgl_parsed.sql_state_code as sql_state_code,
- pgl.event_message as event_message,
-
- -- Timing
- pgl_parsed.timestamp as operation_timestamp,
-
- -- Raw data
- pgl as raw_log_data
-
- from postgres_logs as pgl
- cross join unnest(pgl.metadata) as pgl_metadata
- cross join unnest(pgl_metadata.parsed) as pgl_parsed
-
- WHERE
- pgl.id = '${logId}'
- `
- }
|