feat: track upstream request ID and prevent response header override

When proxying through another new-api instance, the upstream
X-Oneapi-Request-Id was overwriting the local one in client responses.
This adds a new `upstream_request_id` field to the logs table, captures
the upstream ID during relay, and filters it from being copied back to
the client. Frontend gains search/filter and detail display support.
This commit is contained in:
CaIon
2026-05-12 21:53:37 +08:00
parent 428e3d91f2
commit aa56667b8f
20 changed files with 112 additions and 32 deletions
@@ -88,6 +88,8 @@ export function CommonLogsFilterBar<TData>(
if (searchParams.group) next.group = searchParams.group
if (searchParams.username) next.username = searchParams.username
if (searchParams.requestId) next.requestId = searchParams.requestId
if (searchParams.upstreamRequestId)
next.upstreamRequestId = searchParams.upstreamRequestId
if (Object.keys(next).length > 0) {
setFilters((prev) => ({ ...prev, ...next }))
@@ -106,6 +108,7 @@ export function CommonLogsFilterBar<TData>(
searchParams.group,
searchParams.username,
searchParams.requestId,
searchParams.upstreamRequestId,
searchParams.type,
])
@@ -161,7 +164,8 @@ export function CommonLogsFilterBar<TData>(
!!filters.token ||
!!filters.username ||
!!filters.channel ||
!!filters.requestId
!!filters.requestId ||
!!filters.upstreamRequestId
const hasAdditionalFilters =
!!filters.model || !!filters.group || !!logType || hasExpandedFilters
@@ -290,6 +294,15 @@ export function CommonLogsFilterBar<TData>(
onKeyDown={handleKeyDown}
className={inputClass}
/>
<Input
placeholder={t('Upstream Request ID')}
value={filters.upstreamRequestId || ''}
onChange={(e) =>
handleChange('upstreamRequestId', e.target.value)
}
onKeyDown={handleKeyDown}
className={inputClass}
/>
</>
}
hasExpandedActiveFilters={hasExpandedFilters}
@@ -519,6 +519,13 @@ export function DetailsDialog(props: DetailsDialogProps) {
mono
/>
)}
{props.log.upstream_request_id && (
<DetailRow
label={t('Upstream Request ID')}
value={props.log.upstream_request_id}
mono
/>
)}
{props.isAdmin && props.log.channel > 0 && (
<DetailRow
+1
View File
@@ -44,6 +44,7 @@ export const usageLogSchema = z.object({
ip: z.string().default(''),
other: z.string().default(''),
request_id: z.string().default(''),
upstream_request_id: z.string().default(''),
})
export type UsageLog = z.infer<typeof usageLogSchema>
+3
View File
@@ -55,6 +55,9 @@ export function buildSearchParams(
...(commonFilters.group && { group: commonFilters.group }),
...(commonFilters.username && { username: commonFilters.username }),
...(commonFilters.requestId && { requestId: commonFilters.requestId }),
...(commonFilters.upstreamRequestId && {
upstreamRequestId: commonFilters.upstreamRequestId,
}),
}
}
case 'drawing': {
+3
View File
@@ -204,6 +204,9 @@ export function buildApiParams(config: {
...(searchParams.requestId
? { request_id: String(searchParams.requestId) }
: {}),
...(searchParams.upstreamRequestId
? { upstream_request_id: String(searchParams.upstreamRequestId) }
: {}),
...buildTimeRangeParams(searchParams, false),
}
+3
View File
@@ -52,6 +52,7 @@ export interface CommonLogFilters extends CommonFilters {
group?: string
username?: string
requestId?: string
upstreamRequestId?: string
}
/**
@@ -267,6 +268,7 @@ export interface GetLogsParams {
channel?: number
group?: string
request_id?: string
upstream_request_id?: string
}
export interface GetLogsResponse {
@@ -290,6 +292,7 @@ export interface GetLogStatsParams {
channel?: number
group?: string
request_id?: string
upstream_request_id?: string
}
export interface GetLogStatsResponse {