PailUsage GuidesScoped Loggers

Scoped Loggers

Organize logs by context using scoped loggers

Last updated:

Scoped Loggers

Scoped loggers allow you to organize logs by context, making it easier to track messages from specific modules, features, or components.

Basic Scoping

Create a scoped logger by calling scope():

import { pail } from "@visulima/pail";

const authLogger = pail.scope("auth");
authLogger.info("User logged in"); // Includes scope: ["auth"]

Multiple Scope Levels

You can nest scopes for hierarchical organization:

const apiLogger = pail.scope("api", "users");
apiLogger.info("Fetching user"); // Includes scope: ["api", "users"]

Scoped Logger Instance

The scope() method returns a new logger instance with the scope applied:

const logger = createPail();
const scopedLogger = logger.scope("database");

scopedLogger.info("Connected"); // Has scope
logger.info("General message"); // No scope (original logger unchanged)

Removing Scope

Remove the current scope:

const scopedLogger = logger.scope("auth");
scopedLogger.info("Has scope");

scopedLogger.unscope();
scopedLogger.info("No scope");

Usage Patterns

Module-Level Scoping

// auth.ts
import { pail } from "@visulima/pail";

const logger = pail.scope("auth");

export const login = (username: string) => {
    logger.info("Attempting login", { username });
    // ...
};

Feature-Level Scoping

// payment.ts
import { pail } from "@visulima/pail";

const paymentLogger = pail.scope("payment", "processing");

export const processPayment = (amount: number) => {
    paymentLogger.info("Processing payment", { amount });
    // ...
};

Request-Level Scoping

// middleware.ts
import { createPail } from "@visulima/pail";

const logger = createPail();

export const requestLogger = (req: Request, res: Response, next: NextFunction) => {
    const requestId = req.headers["x-request-id"] || generateId();
    const scopedLogger = logger.scope("request", requestId);

    req.logger = scopedLogger; // Attach to request
    scopedLogger.info("Request received", { method: req.method, path: req.path });

    next();
};

Component Scoping (React Example)

// UserProfile.tsx
import { pail } from "@visulima/pail";

const logger = pail.scope("UserProfile");

const UserProfile = () => {
    useEffect(() => {
        logger.info("Component mounted");

        return () => {
            logger.info("Component unmounted");
        };
    }, []);

    // ...
};

Scope Display

Scopes are displayed differently depending on the reporter:

PrettyReporter

[api] [users] info Fetching user

JsonReporter

{
    "scope": ["api", "users"],
    "type": { "name": "info", "level": "informational" },
    "message": "Fetching user"
}

Best Practices

  1. Use descriptive names - Make scopes meaningful
  2. Keep scope hierarchy shallow - Usually 1-3 levels is enough
  3. Scope at module boundaries - Create scopes at module/feature level
  4. Consistent naming - Use consistent scope naming across your app
  5. Don't over-scope - Not every function needs its own scope

Advanced: Dynamic Scoping

You can create scopes dynamically:

const createModuleLogger = (moduleName: string) => {
    return pail.scope("module", moduleName);
};

const authLogger = createModuleLogger("auth");
const userLogger = createModuleLogger("user");
Support

Contribute to our work and keep us going

Community is the heart of open source. The success of our packages wouldn't be possible without the incredible contributions of users, testers, and developers who collaborate with us every day.Want to get involved? Here are some tips on how you can make a meaningful impact on our open source projects.

Ready to help us out?

Be sure to check out the package's contribution guidelines first. They'll walk you through the process on how to properly submit an issue or pull request to our repositories.

Submit a pull request

Found something to improve? Fork the repo, make your changes, and open a PR. We review every contribution and provide feedback to help you get merged.

Good first issues

Simple issues suited for people new to open source development, and often a good place to start working on a package.
View good first issues