Scratch space for learning atproto app development

Remove request-logger middleware

Changed files
+1 -110
src
-1
package.json
···
"kysely": "^0.27.4",
"multiformats": "^9.9.0",
"pino": "^9.3.2",
-
"pino-http": "^10.0.0",
"uhtml": "^4.5.9"
},
"devDependencies": {
-100
src/middleware/requestLogger.ts
···
-
import { randomUUID } from 'node:crypto'
-
import type { IncomingMessage, ServerResponse } from 'node:http'
-
import type { Request, RequestHandler, Response } from 'express'
-
import type { LevelWithSilent } from 'pino'
-
import { type CustomAttributeKeys, type Options, pinoHttp } from 'pino-http'
-
-
import { env } from '#/env'
-
-
enum LogLevel {
-
Fatal = 'fatal',
-
Error = 'error',
-
Warn = 'warn',
-
Info = 'info',
-
Debug = 'debug',
-
Trace = 'trace',
-
Silent = 'silent',
-
}
-
-
type PinoCustomProps = {
-
request: Request
-
response: Response
-
error: Error
-
responseBody: unknown
-
}
-
-
const requestLogger = (options?: Options): RequestHandler[] => {
-
const pinoOptions: Options = {
-
enabled: env.isProduction,
-
customProps: customProps as unknown as Options['customProps'],
-
redact: [],
-
genReqId,
-
customLogLevel,
-
customSuccessMessage,
-
customReceivedMessage: (req) => `request received: ${req.method}`,
-
customErrorMessage: (_req, res) =>
-
`request errored with status code: ${res.statusCode}`,
-
customAttributeKeys,
-
...options,
-
}
-
return [responseBodyMiddleware, pinoHttp(pinoOptions)]
-
}
-
-
const customAttributeKeys: CustomAttributeKeys = {
-
req: 'request',
-
res: 'response',
-
err: 'error',
-
responseTime: 'timeTaken',
-
}
-
-
const customProps = (req: Request, res: Response): PinoCustomProps => ({
-
request: req,
-
response: res,
-
error: res.locals.err,
-
responseBody: res.locals.responseBody,
-
})
-
-
const responseBodyMiddleware: RequestHandler = (_req, res, next) => {
-
const isNotProduction = !env.isProduction
-
if (isNotProduction) {
-
const originalSend = res.send
-
res.send = (content) => {
-
res.locals.responseBody = content
-
res.send = originalSend
-
return originalSend.call(res, content)
-
}
-
}
-
next()
-
}
-
-
const customLogLevel = (
-
_req: IncomingMessage,
-
res: ServerResponse<IncomingMessage>,
-
err?: Error
-
): LevelWithSilent => {
-
if (err || res.statusCode >= 500) return LogLevel.Error
-
if (res.statusCode >= 400) return LogLevel.Warn
-
if (res.statusCode >= 300) return LogLevel.Silent
-
return LogLevel.Info
-
}
-
-
const customSuccessMessage = (
-
req: IncomingMessage,
-
res: ServerResponse<IncomingMessage>
-
) => {
-
if (res.statusCode === 404) return 'Not found'
-
return `${req.method} completed`
-
}
-
-
const genReqId = (
-
req: IncomingMessage,
-
res: ServerResponse<IncomingMessage>
-
) => {
-
const existingID = req.id ?? req.headers['x-request-id']
-
if (existingID) return existingID
-
const id = randomUUID()
-
res.setHeader('X-Request-Id', id)
-
return id
-
}
-
-
export default requestLogger()
+1 -9
src/server.ts
···
import events from 'node:events'
import type http from 'node:http'
-
import express, { type Express, type ErrorRequestHandler } from 'express'
+
import express, { type Express } from 'express'
import { pino } from 'pino'
import { createDb, migrateToLatest } from '#/db'
import { env } from '#/env'
import { Ingester } from '#/firehose/ingester'
-
import requestLogger from '#/middleware/requestLogger'
import { createRouter } from '#/routes'
import { createClient } from '#/auth/client'
import { createResolver } from '#/ident/resolver'
···
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
-
// Request logging
-
app.use(requestLogger)
-
// Routes
const router = createRouter(ctx)
app.use(router)
// Error handlers
app.use((_req, res) => res.sendStatus(404))
-
app.use(((err, _req, res, next) => {
-
res.locals.err = err
-
next(err)
-
}) as ErrorRequestHandler)
const server = app.listen(env.PORT)
await events.once(server, 'listening')