Last active
June 2, 2023 21:09
-
-
Save jordanebelanger/48616ba4ca8d9b050f6f1f5fd207213f to your computer and use it in GitHub Desktop.
stackdriverlogger.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as P from 'pino' | |
import {FastifyReply, FastifyRequest} from 'fastify' | |
const enum PINO_LEVELS { | |
trace = 10, | |
debug = 20, | |
info = 30, | |
warn = 40, | |
error = 50, | |
fatal = 60, | |
} | |
const enum StackdriverSeverity { | |
default = 'DEFAULT', | |
debug = 'DEBUG', | |
info = 'INFO', | |
notice = 'NOTICE', | |
warning = 'WARNING', | |
error = 'ERROR', | |
critical = 'CRITICAL', | |
alert = 'ALERT', | |
emergency = 'EMERGENCY' | |
} | |
function pinoLevelToStackdriverSeverity(level: PINO_LEVELS): StackdriverSeverity { | |
switch (level) { | |
case PINO_LEVELS.trace: | |
case PINO_LEVELS.debug: | |
return StackdriverSeverity.debug | |
case PINO_LEVELS.info: | |
return StackdriverSeverity.info | |
case PINO_LEVELS.warn: | |
return StackdriverSeverity.warning | |
case PINO_LEVELS.error: | |
return StackdriverSeverity.error | |
case PINO_LEVELS.fatal: | |
return StackdriverSeverity.critical | |
default: | |
return StackdriverSeverity.default | |
} | |
} | |
function truncateToDecimalPlace(value: number, decimalPlace: number) { | |
return ( | |
Math.trunc(value * Math.pow(10, decimalPlace)) / Math.pow(10, decimalPlace) | |
) | |
} | |
interface LogEntryHTTPRequest { | |
requestMethod?: string | |
requestUrl?: string | |
requestSize?: string | |
status?: number | |
responseSize?: string | |
userAgent?: string | |
remoteIp?: string | |
serverIp?: string | |
referer?: string | |
latency?: string | |
cacheLookup?: boolean | |
cacheHit?: boolean | |
cacheValidatedWithOriginServer?: boolean | |
cacheFillBytes?: string | |
protocol?: string | |
} | |
interface LogObject { | |
req?: FastifyRequest | |
res?: FastifyReply | |
httpRequest?: LogEntryHTTPRequest | |
requestId?: string | |
} | |
export default function logger(level: P.Level): P.Logger { | |
return P({ | |
messageKey: 'message', | |
timestamp: false, | |
base: undefined, | |
level: level, | |
formatters: { | |
level(_label, number) { | |
return { | |
severity: pinoLevelToStackdriverSeverity(number), | |
} | |
}, | |
log(object: LogObject) { | |
// Setuping the Stackdriver httpRequest property on the log entry | |
if (object.req) { | |
object.httpRequest = { | |
...(object.httpRequest ?? {}, | |
{ | |
requestMethod: object.req.method, | |
requestUrl: object.req.url, | |
userAgent: object.req.headers['user-agent'], | |
remoteIp: object.req.ips?.[0] ?? object.req.ip, | |
protocol: object.req.protocol, | |
}) | |
} | |
} | |
if (object.res) { | |
object.httpRequest = { | |
...(object.httpRequest ?? {}, | |
{ | |
requestMethod: object.res.request.method, | |
requestUrl: object.res.request.url, | |
status: object.res.statusCode, | |
userAgent: object.res.request.headers['user-agent'], | |
latency: `${truncateToDecimalPlace(object.res.getResponseTime() / 1000, 9)}s`, | |
remoteIp: object.res.request.ips?.[0] ?? object.res.request.ip, | |
protocol: object.res.request.protocol, | |
}), | |
} | |
} | |
return object | |
} | |
}, | |
serializers: { | |
// Nullifying the standard Fastify Request/Response serializer for better stackdriver support | |
req(request: FastifyRequest) { return undefined }, | |
res(reply: FastifyReply) { return undefined }, | |
responseTime: function(value) { return undefined } | |
} | |
}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment