Skip to content

Instantly share code, notes, and snippets.

@trvswgnr
Last active September 24, 2024 10:28
Show Gist options
  • Save trvswgnr/0a1521bbe96487fb382981e54077c13b to your computer and use it in GitHub Desktop.
Save trvswgnr/0a1521bbe96487fb382981e54077c13b to your computer and use it in GitHub Desktop.
tagged logger in typescript for node
import { exec, type ChildProcess } from "child_process";
/**
* Enum representing ANSI escape codes for text colors in the terminal.
*
* This enum provides a set of color codes that can be used to add color
* to text output in terminal environments. These colors are commonly
* supported across various terminal emulators.
*
* @example
* const errorMessage = `${Color.Red}Error:${Color.Reset} File not found`;
*
* @see {@link createTaggedLogger} and {@link execTagged} for usage in logging.
*/
export enum Color {
Reset = "\x1b[0m",
Red = "\x1b[31m",
Green = "\x1b[32m",
Yellow = "\x1b[33m",
Blue = "\x1b[34m",
Magenta = "\x1b[35m",
Cyan = "\x1b[36m",
}
/**
* Executes a command in a child process and logs its output with a colored tag.
*
* This function runs a specified command using Node.js's `child_process.exec`,
* and logs both stdout and stderr with a colored tag prefix. It's useful for
* running and monitoring multiple processes simultaneously with distinct visual
* identifiers.
*
* @param cmd - The command to execute in the child process.
* @param tag - A short string used to tag each line of output.
* @param color - The color to use for the tag, from the Color enum.
*
* @returns The ChildProcess instance of the executed command.
*
* @example
* // run a server and log its output in green
* execTagged("bun --hot ./index.ts", "SERVER", Color.Green);
*
* @see {@link createTaggedLogger} for the underlying logging mechanism.
* @see {@link Color} for available color options.
*/
export function execTagged(
cmd: string,
tag: string,
color: Color,
): ChildProcess {
const logger = createTaggedLogger(tag, color);
const childProcess = exec(cmd);
childProcess.stdout?.on("data", logger);
childProcess.stderr?.on("data", logger);
return childProcess;
}
/**
* Creates a logger function that prefixes each line with a colored tag.
*
* This function returns a logging function that buffers incoming data,
* splits it into lines, and logs each line with a colored tag prefix.
* It's designed to work with streams of data, such as those from
* child processes' stdout and stderr.
*
* @param tag - A short string used to tag each line of output.
* @param color - The color to use for the tag, from the Color enum.
*
* @returns A function that takes a chunk of data and logs it with the specified colored tag.
*
* @example
* const logger = createTaggedLogger("SERVER", Color.Green);
* childProcess.stdout.on("data", logger);
* childProcess.stderr.on("data", logger);
*
* // output example:
* // [SERVER] Server started on port 3000
*
* @see {@link Color} for available color options.
* @see {@link execTagged} for a higher-level function that uses this logger.
*/
export function createTaggedLogger(
tag: string,
color: Color,
): (chunk: string) => void {
let buffer = "";
const coloredTag = `${color}[${tag}]${Color.Reset}`;
return (chunk: string) => {
buffer += chunk;
const lines = buffer.split("\n");
for (let i = 0; i < lines.length - 1; i++) {
console.log(`${coloredTag} ${lines[i]}`);
}
buffer = lines[lines.length - 1];
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment