logs: mark aborted/disconnected requests

Massimo Melina committed Sep 14, 2025 at 15:31 UTC 9180a090195c76eed67f5bfc038a8f55d9bc144b
3 files changed +6 -1
admin/src/LogsPage.ts
+2
@@ -349,6 +349,8 @@ export function LogFile({ file, footerSide, hidden, limit, filter, ...rest }: Lo
349 : upload ? `${partial ? "partial " : ""} upload ${extra.speed ? formatSpeed(extra.speed, { sep: ' ' }) : ''}`
350 : row.status === HTTP_UNAUTHORIZED && row.uri?.startsWith(API_URL + 'loginSrp') ? "login failed" + prefix(':\n', extra?.u)
351 : _.map(extra?.params, (v, k) => `${k}: ${v}\n`).join('') + (row.notes || '')
352 + if (extra?.aborted)
353 + row.notes += ' (aborted)'
354 }
355 return row
356 }
src/index.ts
+1
@@ -91,4 +91,5 @@ declare module "koa" {
91 }
92 app.context.isAborted = function() {
93 return this.res.destroyed || this.req.aborted // investigate: "aborted" is deprecated, but "destroyed" will cause failure of some tests
94 + || this.socket.destroyed
95 }
src/log.ts
+3 -1
@@ -76,13 +76,15 @@ export const logMw: Koa.Middleware = async (ctx, next) => {
76 // do it now so it's available for returning plugins
77 ctx.state.completed = Promise.race([ once(ctx.res, 'finish'), once(ctx.res, 'close') ])
78 await next()
79 - console.debug(ctx.status, ctx.method, ctx.originalUrl)
79 + console.debug(ctx.status, ctx.method, ctx.originalUrl, ctx.isAborted() ? '(aborted)' : '')
80 if (!logSpam.get()
81 && (ctx.querystring.includes('{.exec|')
82 || ctx.status === HTTP_NOT_FOUND && /wlwmanifest.xml$|robots.txt$|\.(php)$|cgi/.test(ctx.path))) {
83 events.emit('spam', ctx)
84 return
85 }
86 + if (ctx.isAborted())
87 + ctx.logExtra({ aborted: true })
88 const conn = getConnection(ctx) // collect reference before close
89 // don't await, as we don't want to hold the middlewares chain
90 ctx.state.completed.then(() => {