UNPKG

1.85 kBJavaScriptView Raw
1"use strict"
2const { v4: makeUuid } = require("uuid")
3const reqIdHeader = "X-Request-Id"
4
5module.exports = function createCtxLogger(logger) {
6 const errorHandler = initErrorHandler()
7 const logMiddleware = initLogMiddleware(logger, errorHandler)
8
9 return logMiddleware
10}
11
12function initLogMiddleware(logger, errorHandler) {
13 return async (ctx, next) => {
14 const reqId = ctx.reqId = ctx.request.get(reqIdHeader) || makeUuid()
15 const log = logger.child(reqId)
16 const requestTimer = log.timer()
17
18 ctx.log = log
19 ctx.requestTimer = requestTimer
20
21 try {
22 await next()
23 } catch (e) {
24 await errorHandler(ctx, e)
25 } finally {
26 ctx.response.set("X-Server-Request-Id", ctx.reqId)
27 ctx.requestTimer.end("%s %s > %d", ctx.request.method, ctx.request.url, ctx.response.status)
28 }
29 }
30}
31
32function initErrorHandler() {
33 const handler = async (ctx, e) => {
34 if (e instanceof Error === false) {
35 e = new Error(e)
36 }
37
38 if (!e.status) e.status = 500
39 if (!e.jsonBody) e.jsonBody = {}
40
41 ctx.type = "json"
42 ctx.status = e.status
43
44 ctx.log.error("%s %s < params: %O, body: %O", ctx.request.method, ctx.request.url, ctx.params, ctx.request.body)
45
46 if (!e.expose) {
47 const requestInformation = {
48 method: ctx.method,
49 url: ctx.url,
50 userAgent: ctx.request.get("user-agent"),
51 referrer: ctx.request.get("referrer"),
52 statusCode: ctx.status,
53 remoteAddress: ctx.ip,
54 requestId: ctx.request.get("x-request-id") }
55 ctx.log.error(e, requestInformation)
56 }
57
58 e.jsonBody.status = e.status
59 e.jsonBody.message = e.expose ? e.message : "Error"
60
61 ctx.body = {
62 error: e.jsonBody,
63 reqId: ctx.reqId
64 }
65 }
66 return handler
67}
\No newline at end of file