Last active
February 24, 2025 18:48
-
-
Save jonathanws/1d9cab43510fc10be5433d03b575dac6 to your computer and use it in GitHub Desktop.
Simple Log Framework
This file contains hidden or 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
/** | |
* Service file that takes care of importing all environment variables used, | |
* as well as making sure they're all truthy and correctly typed. | |
*/ | |
import { LOG_LEVELS } from './log.ts' | |
const _LOG_LEVEL = Deno.env.get('LOG_LEVEL') | |
// find() ensures correct typing (don't want just a raw string) | |
export const LOG_LEVEL = LOG_LEVELS.find((l) => l === _LOG_LEVEL) || 'all' |
This file contains hidden or 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
/** | |
* A small "log framework", just to see if I could do it. | |
* | |
* Includes print functions for all specified logging levels, as well as the ability to | |
* disable logs considered too granular for the incoming environment variable log level. | |
*/ | |
import { LOG_LEVEL } from './env.ts' | |
const PRINTABLE_LOG_LEVELS = [ | |
'debug', | |
'info', | |
'warn', | |
'error' | |
] as const | |
type PrintableLogLevel = typeof PRINTABLE_LOG_LEVELS[number] | |
/** | |
* 'off' and 'all' are technically log levels, but we don't want the | |
* developer to be able to use `log.all()`. So we split the arrays. | |
*/ | |
const LOG_LEVELS = [ | |
'off', | |
...PRINTABLE_LOG_LEVELS, | |
'all', | |
] as const | |
type LogLevel = typeof LOG_LEVELS[number] | |
/** | |
* ANSI escape codes. | |
* | |
* Really we could define these strings as an array like above, but I | |
* don't want to memorize `\x1b[33m` as being `yellow`. So we keep them | |
* as an object literal with human-readable keys instead. | |
*/ | |
const RESET_CODE = '\x1b[0m' | |
const COLOR_CODES = { | |
CYAN_CODE: '\x1b[36m', | |
GREEN_CODE: '\x1b[32m', | |
RED_CODE: '\x1b[31m', | |
YELLOW_CODE: '\x1b[33m', | |
} as const | |
type ColorCode = typeof COLOR_CODES[keyof typeof COLOR_CODES] | |
// Colored text will remain colored in the output until manually reset. | |
const getColoredText = (color: ColorCode, message: string) => `${color}${message}${RESET_CODE}` | |
const cyan = (m: string) => getColoredText(COLOR_CODES.CYAN_CODE, m) | |
const green = (m: string) => getColoredText(COLOR_CODES.GREEN_CODE, m) | |
const red = (m: string) => getColoredText(COLOR_CODES.RED_CODE, m) | |
const yellow = (m: string) => getColoredText(COLOR_CODES.YELLOW_CODE, m) | |
type LogFunction = (message: string, a?: any) => void | |
const print = (level: PrintableLogLevel, getColoredText: LogFunction, ...args: [message: string, a?: any]) => { | |
// Do not print a log if the environment log level is lower | |
if (LOG_LEVELS.indexOf(LOG_LEVEL) >= LOG_LEVELS.indexOf(level)) { | |
console.log( | |
...args.map((arg) => typeof arg === 'string' | |
? getColoredText(arg) | |
: arg | |
)) | |
} | |
} | |
const exported: Record<PrintableLogLevel, LogFunction> = { | |
debug: (...args: [message: string, a?: any]) => print('debug', cyan, ...args), | |
error: (...args: [message: string, a?: any]) => print('error', red, ...args), | |
info: (...args: [message: string, a?: any]) => print('info', green, ...args), | |
warn: (...args: [message: string, a?: any]) => print('warn', yellow, ...args), | |
} | |
export default exported | |
export { | |
LOG_LEVELS, | |
type LogLevel, | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment