Severity levels
When you're logging events in your application, not all messages are created equal. Some might be routine information, while others could be critical errors that need immediate attention. That's where severity levels come in. LogTape provides six severity levels to help you categorize your log messages effectively.
Six severity levels
LogTape uses the following severity levels, listed from lowest to highest severity:
- Trace: The most detailed level, used for tracing the flow of execution.
- Debug: Detailed information useful for diagnosing problems.
- Information: General information about the application's operation.
- Warning: An unexpected event that doesn't prevent the application from functioning.
- Error: A significant problem that prevented a specific operation from being completed.
- Fatal error: A critical error that causes the application to abort.
NOTE
Previous versions of LogTape had only five severity levels: Debug, Information, Warning, Error, and Fatal error. The Trace level was introduced in LogTape 0.12.0.
NOTE
LogTape currently does not support custom severity levels.
Let's break down when you might use each of these:
Trace
This API is available since LogTape 0.12.0.
Use this level for very detailed information that is useful for tracing the flow of execution in your application. This is typically used during development or debugging sessions.
logger.trace("Entering function with user {userId}.", { userId });
Debug
Use this level for detailed information that is useful for diagnosing problems. Unlike trace which focuses on execution flow, debug provides contextual information about application state, variable values, and business logic decisions that help identify issues.
logger.debug(
"Database query returned {count} results with params: {queryParams}.",
{ count: results.length, queryParams },
);
Information
This level is for general information about the application's operation.
logger.info("User {username} logged in successfully.", { username });
Warning
Use this when something unexpected happened, but the application can continue functioning. This level is often used for events that are close to causing errors.
logger.warn("API rate limit is close to exceeding, 95% of limit reached.");
Error
This level indicates a significant problem that prevented a specific operation from being completed. Use this for errors that need attention but don't necessarily cause the application to stop.
logger.error(
"Failed to save user data to database.",
{ userId: "12345", error: err },
);
Fatal error
Use this for critical errors that cause the application to abort. Fatal errors are typically unrecoverable and require immediate attention.
logger.fatal("Unrecoverable error: Database connection lost.", { error });
Choosing the right level
When deciding which level to use, consider:
- The impact on the application: How severely does this event affect the application's operation?
- The urgency of response: How quickly does someone need to act on this information?
- The audience: Who needs to see this message? Developers? System administrators? End-users?
Configuring severity levels
This API is available since LogTape 0.8.0.
You can control which severity levels are logged in different parts of your application. For example:
await configure({
// ... other configuration ...
loggers: [
{
category: ["app"],
lowestLevel: "info", // This will log info and above
sinks: ["console"],
},
{
category: ["app", "database"],
lowestLevel: "trace", // This will log everything including trace for database operations
sinks: ["file"],
}
]
});
This configuration will log all levels from "info"
up for most of the app, but will include all levels including "trace"
logs for database operations.
NOTE
The lowestLevel
is applied to the logger itself, not to its sinks. In other words, the lowestLevel
property determines which log records are emitted by the logger. For example, if the parent logger has a lowestLevel
of "debug"
with a sink "console"
, and the child logger has a lowestLevel
of "info"
, the child logger still won't emit "debug"
records to the "console"
sink.
The lowestLevel
property does not inherit from parent loggers, but it is "trace"
by default for all loggers. If you want to make child loggers inherit the severity level from their parent logger, you can use the filters
option instead.
If you want make child loggers inherit the severity level from their parent logger, you can use the filters
option instead:
await configure({
// ... other configuration ...
filters: {
infoAndAbove: "info",
},
loggers: [
{
category: ["app"],
filters: ["infoAndAbove"], // This will log info and above
},
{
category: ["app", "database"],
// This also logs info and above, because it inherits from the parent logger
}
]
});
In this example, the database logger will inherit the infoAndAbove
filter from the parent logger, so it will log all levels from "info"
up.
TIP
The filters
option takes a map of filter names to FilterLike
, where FilterLike
is either a Filter
function or a severity level string. The severity level string will be resolved to a Filter
that filters log records with the specified severity level and above.
See also the Level filter section.
Listing severity levels
This API is available since LogTape 1.0.0.
You can list all available severity levels using the getLogLevels()
function:
import { getLogLevels } from "@logtape/logtape";
const levels = getLogLevels();
for (const level of levels) console.log(level);
The returned array is sorted from lowest to highest severity level:
trace
debug
info
warning
error
fatal
Comparing two severity levels
This API is available since LogTape 0.8.0.
You can compare two severity levels to see which one is more severe by using the compareLogLevel()
function. Since this function returns a number where negative means the first argument is less severe, zero means they are equal, and positive means the first argument is more severe, you can use it with Array.sort()
or Array.toSorted()
to sort severity levels:
import { type LogLevel, compareLogLevel } from "@logtape/logtape";
const levels: LogLevel[] = ["info", "debug", "error", "warning", "fatal", "trace"];
levels.sort(compareLogLevel);
for (const level of levels) console.log(level);
The above code will output:
trace
debug
info
warning
error
fatal
Type for logging methods
This API is available since LogTape 1.0.0.
LogTape provides a type for logging methods like trace()
, debug()
, etc. This type is called LogMethod
and contains all overloaded signatures for logging methods:
import { getLogger, getLogLevels, type LogMethod } from "@logtape/logtape";
const logger = getLogger();
const methods: LogMethod[] = getLogLevels()
.map((level) => logger[level].bind(logger));
Best practices
- Be consistent: Use levels consistently across your application.
- Don't over-use lower levels: Too many debug or info logs can make it harder to find important information.
- Include context: Especially for higher severity levels, include relevant data to help diagnose the issue.
- Consider performance: Remember that logging, especially at lower levels, can impact performance in high-volume scenarios.
By using severity levels effectively, you can create logs that are informative, actionable, and easy to navigate. This will make debugging and monitoring your application much more manageable.