Files
feeddeck/supabase/functions/_shared/utils/log.ts
Rico Berger b8a73cc003 [core] Make Log Level Configurable (#128)
The log level is now configurable, via the `FEEDDECK_LOG_LEVEL`
environment variable. The environment variable can have the following
values: `debug`, `info`, `warning` or `error`.

With this change we also only log the response when getting and parsing
the feed fails when the log level is set to `debug`, also when the
actual message is still an error. This should reduce the noice in the
logs a lot and allows us to specially turn this on while debugging.
2024-02-02 16:52:14 +01:00

102 lines
2.3 KiB
TypeScript

import { FEEDDECK_LOG_LEVEL } from './constants.ts';
export const log = (
level: 'debug' | 'info' | 'warning' | 'error',
message: string,
// deno-lint-ignore no-explicit-any
fields?: Record<string, any>,
) => {
/**
* Check that the provided log level is within the configured log level
* (FEEDDECK_LOG_LEVEL). If this is the case the log line will be printed to
* the console, otherwise it will be ignored.
*/
switch (FEEDDECK_LOG_LEVEL) {
case 'info':
if (level === 'debug') {
return;
}
break;
case 'warning':
if (level === 'debug' || level === 'info') {
return;
}
break;
case 'error':
if (level === 'error' || level === 'warning' || level === 'info') {
return;
}
break;
default:
break;
}
const output = JSON.stringify({
'time': new Date().toUTCString(),
'level': level,
'caller': caller(),
message: message,
...fields,
});
switch (level) {
case 'debug':
console.debug(output);
break;
case 'info':
console.info(output);
break;
case 'warning':
console.warn(output);
break;
case 'error':
console.error(output);
break;
default:
console.log(output);
break;
}
};
/**
* The caller function is used to get the file name of the parent function, so
* that we can add it to each log line.
* See: https://github.com/apiel/caller
*/
interface Bind {
cb?: (file: string) => string;
}
const up = 3;
// deno-lint-ignore no-explicit-any
function caller(this: Bind | any, levelUp = up) {
const err = new Error();
const stack = err.stack?.split('\n')[levelUp];
if (stack) {
return getFile.bind(this)(stack);
}
}
// deno-lint-ignore no-explicit-any
function getFile(this: Bind | any, stack: string) {
stack = stack.substring(stack.indexOf('at ') + 3);
if (!stack.startsWith('file://')) {
stack = stack.substring(stack.lastIndexOf('(') + 1);
}
const path = stack.split(':');
let file;
if (Deno.build.os == 'windows') {
file = `${path[0]}:${path[1]}:${path[2]}:${path[3]}`;
} else {
file = `${path[0]}:${path[1]}:${path[2]}`;
}
if ((this as Bind)?.cb) {
// deno-lint-ignore no-explicit-any
const cb = (this as Bind).cb as any;
file = cb(file);
}
return file;
}