Loggers are objects that you interact with. When you use a logger method it
constructs a LogRecord and passes it down to its handlers for output. To
create custom loggers, specify them in loggers when calling log.setup.
Custom message format
If you want to override default format of message you can define formatter
option for handler. It can a function that takes LogRecord
as argument and outputs string.
The default log format is {levelName} {msg}.
Logging Structured JSON Lines
To output logs in a structured JSON format you can configure most handlers
with a formatter that produces a JSON string. Either use the premade
log.formatters.jsonFormatter or write your own function that takes a
LogRecord and returns a JSON.stringify'd object.
If you want the log to go to stdout then use ConsoleHandler with
the configuration useColors: false to turn off the ANSI terminal colors.
The first argument passed to a log function is always treated as the
message and will be stringified differently. To have arguments JSON.stringify'd
you must pass them after the first.
import*aslogfrom"@std/log";
log.info("This is the message", { thisWillBe:"JSON.stringify'd"}); // {"level":"INFO","datetime":1702501580505,"message":"This is the message","args":{"thisWillBe":"JSON.stringify'd"}}
log.info({ thisWontBe:"JSON.stringify'd"}, "This is an argument"); // {"level":"INFO","datetime":1702501580505,"message":"{\"thisWontBe\":\"JSON.stringify'd\"}","args":"This is an argument"}
Inline Logging
Log functions return the data passed in the msg parameter. Data is returned
regardless if the logger actually logs it.
Lazy Log Evaluation
Some log statements are expensive to compute. In these cases, you can use
lazy log evaluation to prevent the computation taking place if the logger
won't log the message.
NOTE: When using lazy log evaluation, undefined will be returned if the
resolver function is not called because the logger won't log it. It is an
antipattern use lazy evaluation with inline logging because the return value
depends on the current log level.
For module authors
The authors of public modules can let the users display the internal logs of the
module by using a custom logger:
The user of the module can then display the internal logs with:
import * as log from "@std/log";
import { sum } from "/mod.ts";
log.setup({
handlers: {
console: new log.ConsoleHandler("DEBUG"),
},
loggers: {
"my-awesome-module": {
level: "DEBUG",
handlers: ["console"],
},
},
});
sum(1, 2); // prints "running 1 + 2" to the console
Please note that, due to the order of initialization of the loggers, the
following won't work:
import { getLogger } from"@std/log";
constlogger = getLogger("my-awesome-module");
functionsum(a: number, b: number) { logger.debug(`running ${a} + ${b}`); // no message will be logged, because getLogger() was called before log.setup() returna + b; }
Example
import*aslogfrom"@std/log";
// Simple default logger out of the box. You can customize it // by overriding logger and handler named "default", or providing // additional logger configurations. You can log any data type. log.debug("Hello world"); log.info(123456); log.warn(true); log.error({ foo:"bar", fizz:"bazz" }); log.critical("500 Internal server error");
// custom configuration with 2 loggers (the default and `tasks` loggers). log.setup({ handlers: { console:newlog.ConsoleHandler("DEBUG"),
file:newlog.FileHandler("WARN", { filename:"./log.txt", // you can change format of output message using any keys in `LogRecord`. formatter: (record) =>`${record.levelName}${record.msg}`, }), },
loggers: { // configure default logger available via short-hand methods above. default: { level:"DEBUG", handlers: ["console", "file"], },
// get default logger. logger = log.getLogger(); logger.debug("fizz"); // logs to `console`, because `file` handler requires "WARN" level. logger.warn(41256); // logs to both `console` and `file` handlers.
// get custom logger logger = log.getLogger("tasks"); logger.debug("fizz"); // won't get output because this logger has "ERROR" level. logger.error({ productType:"book", value:"126.11" }); // log to `console`.
// if you try to use a logger that hasn't been configured // you're good to go, it gets created automatically with level set to 0 // so no message is logged. constunknownLogger = log.getLogger("mystery"); unknownLogger.info("foobar"); // no-op
functionsomeExpensiveFn(num: number, bool: boolean) { // do some expensive computation }
// not logged, as debug < error. constdata = log.debug(() =>someExpensiveFn(5, true)); console.log(data); // undefined
Handlers are responsible for actual output of log messages. When a handler is
called by a logger, it firstly checks that LogRecord's level is
not lower than level of the handler. If level check passes, handlers formats
log record into string and outputs it to target.
Custom handlers
Custom handlers can be implemented by subclassing BaseHandler or
WriterHandler.
BaseHandler is bare-bones handler that has no output logic at all,
WriterHandler is an abstract class that supports any target with
Writer interface.
During setup async hooks setup and destroy are called, you can use them
to open and close file/HTTP connection or any other action you might need.
For examples check source code of FileHandler`
and TestHandler.
Logging library with support for terminal and file outputs. Also provides interfaces for building custom loggers.
Loggers
Loggers are objects that you interact with. When you use a logger method it constructs a
LogRecordand passes it down to its handlers for output. To create custom loggers, specify them inloggerswhen callinglog.setup.Custom message format
If you want to override default format of message you can define
formatteroption for handler. It can a function that takesLogRecordas argument and outputs string.The default log format is
{levelName} {msg}.Logging Structured JSON Lines
To output logs in a structured JSON format you can configure most handlers with a formatter that produces a JSON string. Either use the premade
log.formatters.jsonFormatteror write your own function that takes aLogRecordand returns a JSON.stringify'd object. If you want the log to go to stdout then useConsoleHandlerwith the configurationuseColors: falseto turn off the ANSI terminal colors.The first argument passed to a log function is always treated as the message and will be stringified differently. To have arguments JSON.stringify'd you must pass them after the first.
Inline Logging
Log functions return the data passed in the
msgparameter. Data is returned regardless if the logger actually logs it.Lazy Log Evaluation
Some log statements are expensive to compute. In these cases, you can use lazy log evaluation to prevent the computation taking place if the logger won't log the message.
For module authors
The authors of public modules can let the users display the internal logs of the module by using a custom logger:
The user of the module can then display the internal logs with:
Please note that, due to the order of initialization of the loggers, the following won't work:
Example
Example
Custom message format example
Example
JSON to stdout with no color example
Example
Custom JSON example
Example
Inline Logging
Example
Lazy Log Evaluation
Handlers are responsible for actual output of log messages. When a handler is called by a logger, it firstly checks that
LogRecord's level is not lower than level of the handler. If level check passes, handlers formats log record into string and outputs it to target.Custom handlers
Custom handlers can be implemented by subclassing
BaseHandleror WriterHandler.BaseHandleris bare-bones handler that has no output logic at all,WriterHandler is an abstract class that supports any target with
Writerinterface.During setup async hooks
setupanddestroyare called, you can use them to open and close file/HTTP connection or any other action you might need.For examples check source code of
FileHandler` and TestHandler.