-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgenericLogger.ts
130 lines (121 loc) · 3.53 KB
/
genericLogger.ts
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// We want to be able to log from anyfile like this:
// log("DEBUG", "message")
// but to help locate which file is doing the logging, we want per-file:
// const log = logFn("src.features.signIn.ScoreBridgeAuthenticator")
// to then use in the above message
// But we want to configure only once:
// 1) the config
// 2) how to format the resulting message
// 3) where to send it (like console.log or a file)
// so at the per-repo-level, bare bones example:
// const config = JSON.parse(
// readRelativeUtf8FileSync("config.json"),
// ) as LoggingConfig;
// const getPrintFn = (message) => {
// return ({ requestedCat, requestedLevel }: PrintFnParams) => {
// console.log(
// `${new Date().toJSON()} ${requestedCat} ${requestedLevel} ${message}`,
// );
// };
// };
// export const logFn = withConfigProvideLogFn(config, getPrintFn);
// in order to provide the const log = logFn(), call above
const levelToInt = {
trace: 100,
debug: 200,
info: 300,
warn: 400,
error: 500,
fatal: 600,
};
export type LogLevel = keyof typeof levelToInt;
export type LoggingConfig = Record<string, LogLevel>;
export interface PrintFnParams {
matchingConfigCat: string;
matchingConfigLevel: string;
requestedLevel: LogLevel;
requestedCat: string;
}
function genericLogger(loggingConfig: LoggingConfig) {
return (
category: string,
logLevel: LogLevel,
printFn: (p: PrintFnParams) => void,
) => {
const matchingConfigCat = Object.keys(loggingConfig).reduce<string | null>(
(acc, configKey) => {
if (category.startsWith(configKey)) {
if (!acc || acc.length <= configKey.length) {
return configKey;
}
}
return acc;
},
null,
);
if (
matchingConfigCat !== null && // default is OFF
levelToInt[logLevel] >= levelToInt[loggingConfig[matchingConfigCat]]
) {
printFn({
matchingConfigLevel: loggingConfig[matchingConfigCat],
matchingConfigCat: matchingConfigCat,
requestedLevel: logLevel,
requestedCat: category,
});
}
};
}
export function withConfigProvideLogFn(
config: LoggingConfig,
printFnProvider: (...addlParams: unknown[]) => (p: PrintFnParams) => void,
) {
return (catPrefix: string) => {
return (
catSuffix: string,
logLevel: LogLevel,
...addlParams: unknown[]
) => {
genericLogger(config)(
catPrefix + catSuffix,
logLevel,
printFnProvider(...addlParams),
);
};
};
}
import fileLoggingConfig from "./loggingConfig.json";
export const getPrintFn = (...addlParams: unknown[]) => {
return ({
matchingConfigCat,
matchingConfigLevel,
requestedLevel,
requestedCat,
}: PrintFnParams) => {
const remainingKey = requestedCat.slice(matchingConfigCat.length);
console.log(
`${new Date().toJSON()} ${requestedLevel.toLocaleUpperCase()} (${matchingConfigCat}@${matchingConfigLevel.toLocaleUpperCase()})${remainingKey}`,
...addlParams,
);
};
};
// console.log(
// `Loaded-for-default filesystem logging config:\n${JSON.stringify(
// fileLoggingConfig,
// )}`,
// );
export function currentConfig(envConfigStr: string | undefined) {
if (envConfigStr) {
let envConfigObj;
try {
envConfigObj = JSON.parse(envConfigStr) as LoggingConfig;
} catch {
console.error(
"Unable to parse logging config from env var, falling back to file.",
);
return fileLoggingConfig as LoggingConfig;
}
return envConfigObj;
}
return fileLoggingConfig as LoggingConfig;
}