Skip to content

Commit

Permalink
feat(logging): implement fluentd reporter
Browse files Browse the repository at this point in the history
closes #370
  • Loading branch information
ygrishajev committed Sep 18, 2024
1 parent 6c78b9b commit 9786654
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 15 deletions.
3 changes: 2 additions & 1 deletion apps/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@
"node-fetch": "^2.6.1",
"pg": "^8.12.0",
"pg-hstore": "^2.3.4",
"pino": "^9.2.0",
"pino": "^9.4.0",
"pino-fluentd": "^0.2.4",
"pino-pretty": "^11.2.1",
"postgres": "^3.4.4",
"protobufjs": "^6.11.2",
Expand Down
5 changes: 4 additions & 1 deletion apps/api/src/core/config/env.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ import { z } from "zod";

const envSchema = z.object({
LOG_LEVEL: z.enum(["fatal", "error", "warn", "info", "debug", "trace"]).optional().default("info"),
STD_OUT_LOG_FORMAT: z.enum(["json", "pretty"]).optional().default("json"),
FLUENTD_TAG: z.string().optional().default("pino"),
FLUENTD_HOST: z.string().optional(),
FLUENTD_PORT: z.number({ coerce: true }).optional().default(24224),
NODE_ENV: z.enum(["development", "production", "test"]).optional().default("development"),
LOG_FORMAT: z.enum(["json", "pretty"]).optional().default("json"),
// TODO: make required once billing is in prod
POSTGRES_DB_URI: z.string().optional(),
POSTGRES_MAX_CONNECTIONS: z.number({ coerce: true }).optional().default(20),
Expand Down
55 changes: 50 additions & 5 deletions apps/api/src/core/services/logger/logger.service.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,67 @@
import { isHttpError } from "http-errors";
import pino, { Bindings, LoggerOptions } from "pino";
import pino, { Bindings } from "pino";
import pinoFluentd from "pino-fluentd";
import pretty from "pino-pretty";
import { Writable } from "stream";

import { config } from "@src/core/config";

export class LoggerService {
protected pino: pino.Logger;

readonly isPretty = config.LOG_FORMAT === "pretty";
readonly isPretty = config.STD_OUT_LOG_FORMAT === "pretty";

constructor(bindings?: Bindings) {
const options: LoggerOptions = { level: config.LOG_LEVEL };
this.pino = this.initPino(bindings);
}

private initPino(bindings?: Bindings): pino.Logger {
const destinations: Writable[] = [];

if (this.isPretty) {
destinations.push(pretty({ sync: true }));
} else {
destinations.push(process.stdout);
}

this.pino = pino(options, config.NODE_ENV === "production" ? undefined : pretty({ sync: true }));
const fluentd = this.initFluentd();

if (fluentd) {
destinations.push(fluentd);
}

let instance = pino({ level: config.LOG_LEVEL }, this.combineDestinations(destinations));

if (bindings) {
this.pino = this.pino.child(bindings);
instance = instance.child(bindings);
}

return instance;
}

private initFluentd(): Writable | undefined {
const isFluentdEnabled = !!(config.FLUENTD_HOST && config.FLUENTD_PORT && config.FLUENTD_TAG);

if (isFluentdEnabled) {
return pinoFluentd({
tag: config.FLUENTD_TAG,
host: config.FLUENTD_HOST,
port: config.FLUENTD_PORT,
"trace-level": config.LOG_LEVEL
});
}
}

private combineDestinations(destinations: Writable[]): Writable {
return new Writable({
write(chunk, encoding, callback) {
for (const destination of destinations) {
destination.write(chunk, encoding);
}

callback();
}
});
}

info(message: any) {
Expand Down
12 changes: 12 additions & 0 deletions apps/api/src/types/pino-fluentd.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
declare module "pino-fluentd" {
import { Writable } from "stream";

interface PinoFluentdOptions {
tag: string;
host: string;
port: number;
"trace-level": string;
}

export default function pinoFluentd(options: PinoFluentdOptions): Writable;
}
2 changes: 1 addition & 1 deletion apps/api/webpack.dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ module.exports = {
extensions: [".ts", ".js"],
alias: hq.get("webpack")
},
externals: [nodeExternals()],
externals: [nodeExternals(), { "winston-transport": "commonjs winston-transport" }],
module: {
rules: [
{
Expand Down
2 changes: 1 addition & 1 deletion apps/api/webpack.prod.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ module.exports = {
extensions: [".ts", ".js"],
alias: hq.get("webpack")
},
externals: [nodeExternals()],
externals: [nodeExternals(), { "winston-transport": "commonjs winston-transport" }],
module: {
rules: [
{
Expand Down
89 changes: 83 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 9786654

Please sign in to comment.