Add GCP logging extender (#503)
* Add GCP logging extender * Minor version bump for new API * Update packages/logger/src/logger.ts Co-Authored-By: kylecarbs <kyle@kwc.io>
This commit is contained in:
parent
e907dbe7e6
commit
8a4da542ae
@ -5,9 +5,12 @@
|
|||||||
"build": "tsc -p tsconfig.build.json && cp ./out/packages/logger/src/* ./out && rm -rf out/packages && ../../node_modules/.bin/webpack --config ./webpack.config.js",
|
"build": "tsc -p tsconfig.build.json && cp ./out/packages/logger/src/* ./out && rm -rf out/packages && ../../node_modules/.bin/webpack --config ./webpack.config.js",
|
||||||
"postinstall": "if [ ! -d out ];then npm run build; fi"
|
"postinstall": "if [ ! -d out ];then npm run build; fi"
|
||||||
},
|
},
|
||||||
"version": "1.0.3",
|
"version": "1.1.0",
|
||||||
"main": "out/main.js",
|
"main": "out/main.js",
|
||||||
"types": "out/index.d.ts",
|
"types": "out/index.d.ts",
|
||||||
"author": "Coder",
|
"author": "Coder",
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@google-cloud/logging": "^4.5.2"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
12
packages/logger/src/extender.test.ts
Normal file
12
packages/logger/src/extender.test.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { field, logger } from "./logger";
|
||||||
|
import { createStackdriverExtender } from "./extender";
|
||||||
|
|
||||||
|
describe("Extender", () => {
|
||||||
|
it("should add stackdriver extender", () => {
|
||||||
|
logger.extend(createStackdriverExtender("coder-dev-1", "logging-package-tests"));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should log", async () => {
|
||||||
|
logger.debug("Bananas!", field("frog", { hi: "wow" }));
|
||||||
|
});
|
||||||
|
});
|
63
packages/logger/src/extender.ts
Normal file
63
packages/logger/src/extender.ts
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
import * as gcl from "@google-cloud/logging";
|
||||||
|
import { Extender, logger, field } from "./logger";
|
||||||
|
|
||||||
|
export const createStackdriverExtender = (projectId: string, logId: string): Extender => {
|
||||||
|
enum GcpLogSeverity {
|
||||||
|
DEFAULT = 0,
|
||||||
|
DEBUG = 100,
|
||||||
|
INFO = 200,
|
||||||
|
NOTICE = 300,
|
||||||
|
WARNING = 400,
|
||||||
|
ERROR = 500,
|
||||||
|
CRITICAL = 600,
|
||||||
|
ALERT = 700,
|
||||||
|
EMERGENCY = 800,
|
||||||
|
}
|
||||||
|
|
||||||
|
const logging = new gcl.Logging({
|
||||||
|
autoRetry: true,
|
||||||
|
projectId,
|
||||||
|
});
|
||||||
|
|
||||||
|
const log = logging.log(logId);
|
||||||
|
const convertSeverity = (severity: "trace" | "info" | "warn" | "debug" | "error"): GcpLogSeverity => {
|
||||||
|
switch (severity) {
|
||||||
|
case "trace":
|
||||||
|
case "debug":
|
||||||
|
return GcpLogSeverity.DEBUG;
|
||||||
|
case "info":
|
||||||
|
return GcpLogSeverity.INFO;
|
||||||
|
case "error":
|
||||||
|
return GcpLogSeverity.ERROR;
|
||||||
|
case "warn":
|
||||||
|
return GcpLogSeverity.WARNING;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (options): void => {
|
||||||
|
const severity = convertSeverity(options.type);
|
||||||
|
// tslint:disable-next-line:no-any
|
||||||
|
const metadata = {} as any;
|
||||||
|
if (options.fields) {
|
||||||
|
options.fields.forEach((f) => {
|
||||||
|
if (!f) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
metadata[f.identifier] = f.value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const entry = log.entry({
|
||||||
|
// tslint:disable-next-line:no-any
|
||||||
|
severity: severity as any,
|
||||||
|
}, {
|
||||||
|
...metadata,
|
||||||
|
message: options.message,
|
||||||
|
});
|
||||||
|
|
||||||
|
log.write(entry).catch((ex) => {
|
||||||
|
logger.named("GCP").error("Failed to log", field("error", ex));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
@ -59,6 +59,14 @@ export const field = <T>(name: string, value: T): Field<T> => {
|
|||||||
return new Field(name, value);
|
return new Field(name, value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type Extender = (msg: {
|
||||||
|
message: string,
|
||||||
|
level: Level,
|
||||||
|
type: "trace" | "info" | "warn" | "debug" | "error",
|
||||||
|
fields?: FieldArray,
|
||||||
|
section?: string,
|
||||||
|
}) => void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This formats & builds text for logging.
|
* This formats & builds text for logging.
|
||||||
* It should only be used to build one log item at a time since it stores the
|
* It should only be used to build one log item at a time since it stores the
|
||||||
@ -221,6 +229,7 @@ export class Logger {
|
|||||||
private _formatter: Formatter,
|
private _formatter: Formatter,
|
||||||
private readonly name?: string,
|
private readonly name?: string,
|
||||||
private readonly defaultFields?: FieldArray,
|
private readonly defaultFields?: FieldArray,
|
||||||
|
private readonly extenders: Extender[] = [],
|
||||||
) {
|
) {
|
||||||
if (name) {
|
if (name) {
|
||||||
this.nameColor = this.hashStringToColor(name);
|
this.nameColor = this.hashStringToColor(name);
|
||||||
@ -248,6 +257,10 @@ export class Logger {
|
|||||||
this.muted = true;
|
this.muted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public extend(extender: Extender): void {
|
||||||
|
this.extenders.push(extender);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Outputs information.
|
* Outputs information.
|
||||||
*/
|
*/
|
||||||
@ -328,7 +341,7 @@ export class Logger {
|
|||||||
* Each name is deterministically generated a color.
|
* Each name is deterministically generated a color.
|
||||||
*/
|
*/
|
||||||
public named(name: string, ...fields: FieldArray): Logger {
|
public named(name: string, ...fields: FieldArray): Logger {
|
||||||
const l = new Logger(this._formatter, name, fields);
|
const l = new Logger(this._formatter, name, fields, this.extenders);
|
||||||
if (this.muted) {
|
if (this.muted) {
|
||||||
l.mute();
|
l.mute();
|
||||||
}
|
}
|
||||||
@ -393,6 +406,16 @@ export class Logger {
|
|||||||
console.log(...this._formatter.flush());
|
console.log(...this._formatter.flush());
|
||||||
}
|
}
|
||||||
// tslint:enable no-console
|
// tslint:enable no-console
|
||||||
|
|
||||||
|
this.extenders.forEach((extender) => {
|
||||||
|
extender({
|
||||||
|
section: this.name,
|
||||||
|
fields: options.fields,
|
||||||
|
level: options.level,
|
||||||
|
message: options.message as string,
|
||||||
|
type: options.type,
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user