
Product
Introducing Webhook Events for Alert Changes
Add real-time Socket webhook events to your workflows to automatically receive software supply chain alert changes in real time.
@decaf-ts/logging
Advanced tools
A small, flexible TypeScript logging library designed for framework-agnostic projects. It provides:
Documentation available here
Minimal size: 5.5 KB kb gzipped
The logging package is a lightweight, extensible logging solution for TypeScript projects. It centers on two main constructs:
It also offers:
Core files and their roles
src/types.ts: Type definitions and contracts
src/constants.ts: Defaults and enums
src/logging.ts: Implementations and static facade
src/decorators.ts: Method decorators
src/LoggedClass.ts: Base convenience class
src/winston/winston.ts: Optional Winston adapter
Design principles
Key behaviors
Public API surface
Intended usage
This guide provides concise, non-redundant examples for each public API. Examples are inspired by the package’s unit tests and reflect real usage.
Note: Replace the import path with your actual package name. In this monorepo, tests import from "../../src".
Basic setup and global logging via Logging Description: Configure global logging and write messages through the static facade, similar to unit tests that verify console output and level filtering.
import { Logging, LogLevel } from "@decaf-ts/logging";
// Set global configuration
Logging.setConfig({
level: LogLevel.debug, // allow debug and above
style: false, // plain output (tests use both styled and themeless)
timestamp: false, // omit timestamp for simplicity in this example
});
// Log using the global logger
Logging.info("Application started");
Logging.debug("Debug details");
Logging.error("Something went wrong");
// Verbosity-controlled logs (silly delegates to verbose internally)
Logging.setConfig({ verbose: 2 });
Logging.silly("Extra details at verbosity 1"); // emitted when verbose >= 1
Logging.verbose("Even more details", 2); // only with verbose >= 2
Create a class-scoped logger and child method logger Description: Create a logger bound to a specific context (class) and derive a child logger for a method, matching patterns used in tests.
import { Logging, LogLevel } from "@decaf-ts/logging";
Logging.setConfig({ level: LogLevel.debug });
// A class-scoped logger
const classLogger = Logging.for("UserService");
classLogger.info("Fetching users");
// A child logger for a specific method with temporary config overrides
const methodLogger = classLogger.for("list", { style: false });
methodLogger.debug("Querying repository...");
MiniLogger: direct use and per-instance config Description: Instantiate MiniLogger directly (the default implementation behind Logging.setFactory). Tests create MiniLogger with and without custom config.
import { MiniLogger, LogLevel, type LoggingConfig } from "@decaf-ts/logging";
const logger = new MiniLogger("TestContext");
logger.info("Info from MiniLogger");
// With custom configuration
const custom: Partial<LoggingConfig> = { level: LogLevel.debug, verbose: 2 };
const customLogger = new MiniLogger("TestContext", custom);
customLogger.debug("Debug with custom level");
// Child logger with correlation id
const traced = customLogger.for("run", { correlationId: "req-123" });
traced.info("Tracing this operation");
Decorators: log, debug, info, verbose, silly Description: Instrument methods to log calls and optional benchmarks. Tests validate decorator behavior for call and completion messages.
import { log, debug, info as infoDecor, verbose as verboseDecor, silly as sillyDecor, LogLevel, Logging } from "@decaf-ts/logging";
// Configure logging for demo
Logging.setConfig({ level: LogLevel.debug, style: false, timestamp: false });
class AccountService {
@log(LogLevel.info) // logs method call with args
create(name: string) {
return { id: "1", name };
}
@debug(true) // logs call and completion time at debug level
rebuildIndex() {
// heavy work...
return true;
}
@info() // convenience wrapper for info level
enable() {
return true;
}
@verbose(1, true) // verbose with verbosity threshold and benchmark
syncAll() {
return Promise.resolve("ok");
}
@silly() // very chatty, only emitted when verbose allows
ping() {
return "pong";
}
}
const svc = new AccountService();
svc.create("Alice");
svc.rebuildIndex();
svc.enable();
await svc.syncAll();
svc.ping();
LoggedClass: zero-boilerplate logging inside classes Description: Extend LoggedClass to gain a protected this.log with the correct context (class name). Tests use Logging.for to build similar context.
import { LoggedClass } from "@your-scope/logging";
class UserRepository extends LoggedClass {
findById(id: string) {
this.log.info(`Finding ${id}`);
return { id };
}
}
const repo = new UserRepository();
repo.findById("42");
Winston integration: swap the logger factory Description: Route all logging through WinstonLogger by installing WinstonFactory. This mirrors the optional adapter in src/winston.
import { Logging } from "@your-scope/logging";
import { WinstonFactory } from "@your-scope/logging/winston/winston";
// Install Winston as the logger factory
Logging.setFactory(WinstonFactory);
// Now any logger created will use Winston under the hood
const log = Logging.for("ApiGateway");
log.info("Gateway started");
Theming and styling with Logging.theme and config Description: Enable style and customize theme to colorize parts of the log (tests check styled output patterns).
import { Logging, LogLevel, DefaultTheme, type Theme } from "@your-scope/logging";
// Enable styling globally
Logging.setConfig({ style: true, timestamp: true, context: false });
// Optionally override theme: make debug level yellow (fg:33) and error red+bold
const theme: Theme = {
...DefaultTheme,
logLevel: {
...DefaultTheme.logLevel,
debug: { fg: 33 },
error: { fg: 31, style: ["bold"] },
},
};
// Apply at runtime by passing to Logging.theme where needed (MiniLogger does this internally)
const styled = Logging.theme("debug", "logLevel", LogLevel.debug, theme);
// Regular logging picks up style=true and formats output accordingly
Logging.debug("This is a styled debug message");
Factory basics and because(reason, id) Description: Create ad-hoc, labeled loggers and use factory semantics.
import { Logging } from "@your-scope/logging";
// Ad-hoc logger labeled with a reason and optional id (handy for correlation)
const jobLog = Logging.because("reindex", "job-77");
jobLog.info("Starting reindex");
Types: Logger and LoggingConfig in your code Description: Use the library’s types for better APIs.
import type { Logger, LoggingConfig } from "@your-scope/logging";
export interface ServiceDeps {
log: Logger;
config?: Partial<LoggingConfig>;
}
export class PaymentService {
constructor(private deps: ServiceDeps) {}
charge(amount: number) {
this.deps.log.info(`Charging ${amount}`);
}
}
If you have bug reports, questions or suggestions please create a new issue.
I am grateful for any contributions made to this project. Please read this to get started.
The first and easiest way you can support it is by Contributing. Even just finding a typo in the documentation is important.
Financial support is always welcome and helps keep both me and the project alive and healthy.
So if you can, if this project in any way. either by learning something or simply by helping you save precious time, please consider donating.
This project is released under the MIT License.
By developers, for developers...
FAQs
simple winston inspired wrapper for cross lib logging
We found that @decaf-ts/logging demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 5 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Product
Add real-time Socket webhook events to your workflows to automatically receive software supply chain alert changes in real time.

Security News
ENISA has become a CVE Program Root, giving the EU a central authority for coordinating vulnerability reporting, disclosure, and cross-border response.

Product
Socket now scans OpenVSX extensions, giving teams early detection of risky behaviors, hidden capabilities, and supply chain threats in developer tools.