-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlogger.ts
60 lines (52 loc) · 1.48 KB
/
logger.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
import type { Router } from "./router.ts";
import type { Context } from "./context.ts";
import type { Route } from "./route.ts";
import type { Handler } from "./handler.ts";
import { nanoid } from "@jlarky/nanoid";
import * as E from "fun/either";
import { pipe } from "fun/fn";
import { map } from "fun/array";
import { route } from "./route.ts";
const stringify = E.tryCatch(JSON.stringify, String);
const tryLog = (data: unknown): void =>
pipe(
stringify(data),
E.match(
(err) =>
console.error({
timestamp: Date.now(),
msg: "Unable to log data",
err,
}),
console.log,
),
);
export function logHandler<S, V, O>(
handler: Handler<Context<S, V>, Response, O>,
): Handler<Context<S, V>, Response, O> {
return async (ctx) => {
const start = Date.now();
const id = nanoid();
const { request, state, path } = ctx;
const { method, url } = request;
tryLog({ id, timestamp: start, method, url, state, path });
const output = await handler(ctx);
const [response] = output;
const { status } = response;
const end = Date.now();
const responseTime = end - start;
tryLog({
id,
timestamp: end,
responseTime,
status,
});
return output;
};
}
export function logRoute<S, V>(r: Route<V, S>): Route<V, S> {
return route(r.route, r.parser, logHandler(r.handler));
}
export function logRouter<S>(router: Router<S>): Router<S> {
return pipe(router, map(logRoute));
}