-
-
Notifications
You must be signed in to change notification settings - Fork 579
/
index.ts
96 lines (81 loc) · 2.34 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/**
* @module
* Logger Middleware for Hono.
*/
import type { MiddlewareHandler } from '../../types'
import { getColorEnabled } from '../../utils/color'
import { getPath } from '../../utils/url'
enum LogPrefix {
Outgoing = '-->',
Incoming = '<--',
Error = 'xxx',
}
const humanize = (times: string[]) => {
const [delimiter, separator] = [',', '.']
const orderTimes = times.map((v) => v.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1' + delimiter))
return orderTimes.join(separator)
}
const time = (start: number) => {
const delta = Date.now() - start
return humanize([delta < 1000 ? delta + 'ms' : Math.round(delta / 1000) + 's'])
}
const colorStatus = (status: number) => {
const colorEnabled = getColorEnabled()
if (colorEnabled) {
switch ((status / 100) | 0) {
case 5: // red = error
return `\x1b[31m${status}\x1b[0m`
case 4: // yellow = warning
return `\x1b[33m${status}\x1b[0m`
case 3: // cyan = redirect
return `\x1b[36m${status}\x1b[0m`
case 2: // green = success
return `\x1b[32m${status}\x1b[0m`
}
}
// Fallback to unsupported status code.
// E.g.) Bun and Deno supports new Response with 101, but Node.js does not.
// And those may evolve to accept more status.
return `${status}`
}
type PrintFunc = (str: string, ...rest: string[]) => void
function log(
fn: PrintFunc,
prefix: string,
method: string,
path: string,
status: number = 0,
elapsed?: string
) {
const out =
prefix === LogPrefix.Incoming
? `${prefix} ${method} ${path}`
: `${prefix} ${method} ${path} ${colorStatus(status)} ${elapsed}`
fn(out)
}
/**
* Logger Middleware for Hono.
*
* @see {@link https://hono.dev/docs/middleware/builtin/logger}
*
* @param {PrintFunc} [fn=console.log] - Optional function for customized logging behavior.
* @returns {MiddlewareHandler} The middleware handler function.
*
* @example
* ```ts
* const app = new Hono()
*
* app.use(logger())
* app.get('/', (c) => c.text('Hello Hono!'))
* ```
*/
export const logger = (fn: PrintFunc = console.log): MiddlewareHandler => {
return async function logger(c, next) {
const { method } = c.req
const path = getPath(c.req.raw)
log(fn, LogPrefix.Incoming, method, path)
const start = Date.now()
await next()
log(fn, LogPrefix.Outgoing, method, path, c.res.status, time(start))
}
}