Skip to content

Commit f5010b4

Browse files
committed
fix: resolve empty Live Request Logs on Vercel and display missing token usage in System Health
1 parent 00334bf commit f5010b4

2 files changed

Lines changed: 60 additions & 29 deletions

File tree

client/src/pages/admin/system.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export default function AdminSystem() {
2929

3030
<Card>
3131
<CardHeader>
32-
<CardTitle>OpenAI Upstream Usage</CardTitle>
32+
<CardTitle>Upstream Provider Usage</CardTitle>
3333
<CardDescription>Recent API calls and costs.</CardDescription>
3434
</CardHeader>
3535
<CardContent>
@@ -50,8 +50,8 @@ export default function AdminSystem() {
5050
<TableCell>{new Date(log.createdAt).toLocaleString()}</TableCell>
5151
<TableCell>{log.provider}</TableCell>
5252
<TableCell className="font-mono text-xs">{log.model}</TableCell>
53-
<TableCell>{log.promptTokens}</TableCell>
54-
<TableCell>{log.completionTokens}</TableCell>
53+
<TableCell>{log.tokensIn}</TableCell>
54+
<TableCell>{log.tokensOut}</TableCell>
5555
<TableCell className="text-right font-mono text-xs">
5656
${Number(log.costUsd).toFixed(4)}
5757
</TableCell>

server/middleware/request-logger.ts

Lines changed: 57 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import geoip from "geoip-lite";
33
import { UAParser } from "ua-parser-js";
44
import { db } from "../db";
55
import { requestLogs } from "@shared/schema";
6+
import { emitAdminRequestUpdate } from "../socket";
67

78
// Helper to mask IP addresses for privacy when visibility is restricted
89
function maskIp(ip: string): string {
@@ -27,7 +28,13 @@ function maskIp(ip: string): string {
2728
export function requestLogger(req: Request, res: Response, next: NextFunction) {
2829
const start = Date.now();
2930

30-
res.on("finish", () => {
31+
const originalEnd = res.end;
32+
let logged = false;
33+
34+
const performLog = async (statusCode: number) => {
35+
if (logged) return;
36+
logged = true;
37+
3138
const responseTimeMs = Date.now() - start;
3239

3340
// Get IP respecting proxy headers
@@ -78,32 +85,56 @@ export function requestLogger(req: Request, res: Response, next: NextFunction) {
7885
const userId = req.user?.id || null;
7986
const sessionId = req.sessionID || "";
8087

81-
// Insert async (don't await to avoid blocking the event loop)
82-
db.insert(requestLogs).values({
83-
userId,
84-
sessionId,
85-
method: req.method,
86-
path: req.originalUrl || req.path,
87-
statusCode: res.statusCode,
88-
responseTimeMs,
89-
ipAddress: finalIpAddress,
90-
userAgent,
91-
device,
92-
browser,
93-
os,
94-
geoCountry,
95-
geoRegion,
96-
geoCity,
97-
geoLat,
98-
geoLng,
99-
}).returning()
100-
.then(([log]) => {
101-
if (log) emitAdminRequestUpdate(log);
102-
})
103-
.catch(err => {
104-
console.error("[RequestLogger] Failed to insert log:", err);
88+
try {
89+
const [log] = await db.insert(requestLogs).values({
90+
userId,
91+
sessionId,
92+
method: req.method,
93+
path: req.originalUrl || req.path,
94+
statusCode,
95+
responseTimeMs,
96+
ipAddress: finalIpAddress,
97+
userAgent,
98+
device,
99+
browser,
100+
os,
101+
geoCountry,
102+
geoRegion,
103+
geoCity,
104+
geoLat,
105+
geoLng,
106+
}).returning();
107+
108+
if (log) emitAdminRequestUpdate(log);
109+
} catch (err) {
110+
console.error("[RequestLogger] Failed to insert log:", err);
111+
}
112+
};
113+
114+
// @ts-ignore
115+
res.end = function(chunk?: any, encodingOrCb?: any, cb?: any) {
116+
let encoding: string | undefined;
117+
let callback: (() => void) | undefined;
118+
119+
if (typeof encodingOrCb === "function") {
120+
callback = encodingOrCb;
121+
encoding = undefined;
122+
} else {
123+
encoding = encodingOrCb;
124+
callback = cb;
125+
}
126+
127+
// Capture the status code before ending
128+
const statusCode = res.statusCode;
129+
130+
// Run the logging before we close the stream.
131+
// This ensures Vercel doesn't kill the lambda before the DB insert completes.
132+
performLog(statusCode)
133+
.finally(() => {
134+
// Now actually end the response
135+
originalEnd.call(res, chunk, encoding, callback);
105136
});
106-
});
137+
};
107138

108139
next();
109140
}

0 commit comments

Comments
 (0)