# Serverless Parent Logs API Plan

## Summary

新增一组 Loki-compatible API, 通过 `control_plane_info` 自动定位 parent/control-plane system Loki datasource, 并在转发到 upstream Loki 前自动注入隔离 label:

```logql
cluster="{env}-{projectID}"
```

以 `control_plane_info=us-east-1-f04/aws-us-east-1/devtier-infra` 为例, 在 prod 环境会注入:

```logql
cluster="prod-us-east-1-f04"
```

## Public API

新增 GET 路由:

- `/data-proxy/serverless-parent-logs/api/v1/query_range`
- `/data-proxy/serverless-parent-logs/api/v1/labels`
- `/data-proxy/serverless-parent-logs/api/v1/label/:name/values`
- `/data-proxy/serverless-parent-logs/api/v1/series`

公共参数:

- `control_plane_info`: 必填, 格式为 `projectID/vendor-region/applicationID`.
- `datasource`, `datasource_uid`, `datasourceUid`, `uid`: 可选 datasource override.
- 其他参数保持 Loki 原语义, 例如 `query`, `match[]`, `start`, `end`, `step`, `limit`, `direction`.

路由规则:

- 默认从 `control_plane_info` 解析 provider/region, 例如 `aws/us-east-1`, 匹配 `loki_proxy.system_endpoints`.
- 如果传入 datasource alias, 优先使用 datasource 解析 endpoint URL.
- `control_plane_info`, datasource aliases, `provider`, `region` 只用于 proxy routing, 不转发给 upstream Loki.

## API Usage

### query_range

用途: 按时间范围查询日志正文, 是实际查日志的接口.

```bash
curl -sS -G 'https://clinic.pingcap.com/data-proxy/serverless-parent-logs/api/v1/query_range' \
  -H "Authorization: Bearer ${CLINIC_API_KEY}" \
  --data-urlencode 'control_plane_info=us-east-1-f04/aws-us-east-1/devtier-infra' \
  --data-urlencode 'query={} != `operator_controller.go`' \
  --data-urlencode 'start=1782562920000000000' \
  --data-urlencode 'end=1782563220000000000' \
  --data-urlencode 'limit=20' \
  --data-urlencode 'direction=backward'
```

转发前 query 会被改写为:

```logql
{cluster="prod-us-east-1-f04"} != `operator_controller.go`
```

### labels

用途: 查询当前 parent/control-plane 日志范围内可用的 label 名称, 用于前端筛选器或 Grafana discovery.

```bash
curl -sS -G 'https://clinic.pingcap.com/data-proxy/serverless-parent-logs/api/v1/labels' \
  -H "Authorization: Bearer ${CLINIC_API_KEY}" \
  --data-urlencode 'control_plane_info=us-east-1-f04/aws-us-east-1/devtier-infra' \
  --data-urlencode 'start=1782562920000000000' \
  --data-urlencode 'end=1782563220000000000'
```

无 `match[]` 时会自动创建:

```logql
match[]={cluster="prod-us-east-1-f04"}
```

### label/:name/values

用途: 查询指定 label 的可选值, 例如查 parent cluster 下有哪些 `container` 或 `namespace`.

```bash
curl -sS -G 'https://clinic.pingcap.com/data-proxy/serverless-parent-logs/api/v1/label/container/values' \
  -H "Authorization: Bearer ${CLINIC_API_KEY}" \
  --data-urlencode 'control_plane_info=us-east-1-f04/aws-us-east-1/devtier-infra' \
  --data-urlencode 'start=1782562920000000000' \
  --data-urlencode 'end=1782563220000000000'
```

### series

用途: 查询匹配条件下有哪些日志流 label 组合, 不返回日志正文.

```bash
curl -sS -G 'https://clinic.pingcap.com/data-proxy/serverless-parent-logs/api/v1/series' \
  -H "Authorization: Bearer ${CLINIC_API_KEY}" \
  --data-urlencode 'control_plane_info=us-east-1-f04/aws-us-east-1/devtier-infra' \
  --data-urlencode 'match[]={container="tidb-gateway"}' \
  --data-urlencode 'start=1782562920000000000' \
  --data-urlencode 'end=1782563220000000000'
```

转发前 `match[]` 会被改写为:

```logql
match[]={container="tidb-gateway", cluster="prod-us-east-1-f04"}
```

## Implementation

- `LokiHandler` 注册 `/data-proxy/serverless-parent-logs/api/v1` 四个 GET endpoint.
- 新增共用 handler, 负责解析 `control_plane_info`, 解析 datasource override, 去除 routing-only query 参数, 构造 proxy URL, 调用 `ProxySystemRequest`.
- `LokiProxyService` 新增 provider/region endpoint 解析能力, 并复用现有 system Loki proxy 转发逻辑.
- 抽取并导出 serverless parent `control_plane_info` 解析逻辑, 供 metrics/logs 共用.
- `query_range` 注入 cluster label 到第一个 LogQL stream selector. 如果 query 没有 stream selector, 返回 400.
- `labels`, `label/:name/values`, `series` 对每个 `match[]` 注入 cluster label; 未传 `match[]` 时创建 cluster-only matcher.
- 如果调用方已经传入 `cluster` matcher, 服务会用 `control_plane_info` 推导出的 cluster 覆盖, 避免重复 matcher 和隔离绕过.
- response status/body/header 透传沿用现有 Loki proxy 行为, 并返回 `X-Loki-Proxy: clinic-data-service`.

## Validation

回归测试:

```bash
go test ./pkg/service ./pkg/handlers -run 'Loki|ServerlessParent' -count=1
```

真实 Loki 查询验证:

- datasource: `Loki-aws-us-east-1`
- upstream: `https://www.ds.us-east-1.aws.observability.tidbcloud.com/loki/self-monitoring`
- LogQL: ``{cluster="prod-us-east-1-f04"} != `operator_controller.go` ``
- time range: `2026-06-27T20:22:00+08:00` 到 `2026-06-27T20:27:00+08:00`
- result: `HTTP 200`, `status=success`, `resultType=streams`, `streams=5`, `lines=20`

## Deployment Note

本地 `configs/config-dataproxy.yaml` 当前没有实际启用 `loki_proxy.system_endpoints`. 部署或本地完整联调时需要在配置中补充 datasource 到 upstream URL 的映射, 例如:

```yaml
loki_proxy:
  system_endpoints:
    - datasource: "Loki-aws-us-east-1"
      provider: "aws"
      region: "us-east-1"
      url: "https://www.ds.us-east-1.aws.observability.tidbcloud.com/loki/self-monitoring"
```
