1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 | const pino = require('pino');
|
13 | const { InterfaceBase } = require('@adobe/helix-log');
|
14 |
|
15 | const serializers = {
|
16 | res: (res) => {
|
17 |
|
18 | if (!res || !res.statusCode) {
|
19 | return res;
|
20 | }
|
21 | return {
|
22 | statusCode: res.statusCode,
|
23 | duration: res.duration,
|
24 | headers: res.getHeaders(),
|
25 | };
|
26 | },
|
27 | req: pino.stdSerializers.req,
|
28 | err: pino.stdSerializers.err,
|
29 | };
|
30 |
|
31 | function pino2hlxLevel(lvl) {
|
32 | if (lvl < 10) {
|
33 | return 'silly';
|
34 | }
|
35 | if (lvl < 20) {
|
36 | return 'trace';
|
37 | }
|
38 | if (lvl < 30) {
|
39 | return 'debug';
|
40 | }
|
41 | if (lvl < 40) {
|
42 | return 'info';
|
43 | }
|
44 | if (lvl < 50) {
|
45 | return 'warn';
|
46 | }
|
47 | if (lvl < 60) {
|
48 | return 'error';
|
49 | }
|
50 | return 'fatal';
|
51 | }
|
52 |
|
53 | class PinoInterface extends InterfaceBase {
|
54 | constructor() {
|
55 | super();
|
56 | this[pino.symbols.needsMetadataGsym] = true;
|
57 | }
|
58 |
|
59 | write() {
|
60 | const {
|
61 | msg,
|
62 | ...fields
|
63 | } = this.lastObj;
|
64 |
|
65 | Object.entries(fields).forEach(([key, value]) => {
|
66 | if (key in serializers) {
|
67 | fields[key] = serializers[key](value);
|
68 | }
|
69 | });
|
70 |
|
71 | const time = this.lastTime;
|
72 | let timestamp;
|
73 | try {
|
74 | timestamp = new Date(Number(time));
|
75 | } catch (e) {
|
76 | timestamp = new Date();
|
77 | }
|
78 | const level = pino2hlxLevel(this.lastLevel);
|
79 | this._logImpl({
|
80 | ...fields,
|
81 | message: [msg],
|
82 | level,
|
83 | timestamp,
|
84 | });
|
85 | }
|
86 | }
|
87 |
|
88 | module.exports = PinoInterface;
|