Files
Jordi Enric d6ca0e5900 feat(studio): migrate API reports to OTEL (#50638)
## Problem

The API Gateway and Data API observability reports still send legacy
BigQuery SQL to the logs.all endpoint. The Data API shared-report hook
also hardcodes logs.all, so the otelReports flag cannot move that report
to ClickHouse.

## Fix

- Add the ClickHouse requests-by-country query needed by API Gateway.
- Select API Gateway SQL and endpoint atomically from otelReports.
- Route the Data API PostgREST report through the existing tested OTEL
API query builders and logs.all.otel.
- Wait for ConfigCat before the Data API sends a request, avoiding an
initial legacy request while the flag loads.
- Keep logs.all behavior when the flag is disabled and leave other
shared reports unchanged.

## How to test

1. Enable otelReports and open API Gateway, then confirm its report
requests use logs.all.otel.
2. Open Data API and confirm all report requests use logs.all.otel with
a request.path filter for /rest.
3. Change the date range, add a filter, and refresh each report.
4. Disable otelReports and confirm both reports use logs.all.

All OTEL query shapes were tested individually against logs.all.otel.
The focused query suite and lint pass locally.

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

- **New Features**
  - API reports can use OpenTelemetry data when enabled.
- Added country-level request reporting, excluding requests without
country information.
- Added OpenTelemetry-backed PostgREST reports and Storage cache
hit/miss metrics.

- **Improvements**
  - Reports wait for required configuration before loading data.
  - Refreshing reports consistently refetches active metrics.
  - Improved error handling for analytics query failures.
- Improved report accuracy with numeric time buckets and more precise
attribute filtering.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-21 18:13:22 +02:00

58 lines
1.4 KiB
TypeScript

import type { LogsEndpointParams } from '@/components/interfaces/Settings/Logs/Logs.types'
import type { SafeLogSqlFragment } from '@/data/logs/safe-analytics-sql'
export type ApiReportRequestParams = Required<
Pick<LogsEndpointParams, 'iso_timestamp_start' | 'iso_timestamp_end'>
>
type SharedApiReportMetricParams<
FilterBy extends string,
QueryName extends string,
Filters extends readonly unknown[],
> = {
filterBy: FilterBy
queryName: QueryName
source: string
filters: Filters
start: string
end: string
projectRef: string
useOtel: boolean
}
export const reportKeys = {
apiMetric: (
projectRef: string | undefined,
queryName: string,
params: ApiReportRequestParams,
sql: SafeLogSqlFragment,
useOtel: boolean
) => ['projects', projectRef, 'api-report', queryName, params, sql, { otel: useOtel }] as const,
allSharedApi: ['shared-api-report'] as const,
sharedApiMetric: <
FilterBy extends string,
QueryName extends string,
Filters extends readonly unknown[],
>({
filterBy,
queryName,
source,
filters,
start,
end,
projectRef,
useOtel,
}: SharedApiReportMetricParams<FilterBy, QueryName, Filters>) =>
[
...reportKeys.allSharedApi,
filterBy,
queryName,
source,
filters,
start,
end,
projectRef,
{ otel: useOtel },
] as const,
}