File size: 1,595 Bytes
fb38ec5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import { FastifyPluginAsync } from "fastify";
import fp from "fastify-plugin";

declare module "fastify" {
  interface FastifyReply {
    startTime: number;
  }
}

// https://github.com/fastify/fastify/blob/main/lib/logger.js#L67
function now() {
  const ts = process.hrtime();
  return ts[0] * 1e3 + ts[1] / 1e6;
}

const logger: FastifyPluginAsync = async (fastify) => {
  fastify.addHook("onRequest", (req, reply, done) => {
    reply.startTime = now();
    done();
  });

  fastify.addHook("onResponse", (req, reply, done) => {
    if (
      req.method !== "OPTIONS" &&
      req.raw.url !== "/status" &&
      req.raw.url !== "/v1/events" &&
      req.raw.url !== "/"
    ) {
      req.log.info(
        {
          ip: getClientIp(req),
          url: req.raw.url,
          method: req.method,
          statusCode: reply.raw.statusCode,
          durationMs: roundMS(now() - reply.startTime),
        },
        "request completed",
      );
    }
    done();
  });
};

export default fp(logger);

function roundMS(num: number): number {
  return Math.trunc(num * 100) / 100;
}

function getClientIp(req: any): string {
  if (req.headers["x-forwarded-for"]) {
    return req.headers["x-forwarded-for"].split(",")[0];
  }
  if (req.headers["x-real-ip"]) {
    return req.headers["x-real-ip"];
  }
  if (req.raw && req.raw.connection) {
    return req.raw.connection.remoteAddress || "unknown";
  }
  if (req.raw && req.raw.socket) {
    return req.raw.socket.remoteAddress || "unknown";
  }
  if (req.socket) {
    return req.socket.remoteAddress || "unknown";
  }
  return "unknown";
}