Loggers are objects that you interact with. When you use logger method it constructs a `LogRecord` and passes it down to its handlers for output. To create custom loggers speficify them in `loggers` when calling `log.setup`.
#### `LogRecord`
`LogRecord` is an object that encapsulates provided message and arguments as well some meta data that can be later used when formatting a message.
```ts
interface LogRecord {
msg: string;
args: any[];
datetime: Date;
level: number;
levelName: string;
}
```
### Handlers
Handlers are responsible for actual output of log messages. When handler is called by 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.
`log` module comes with two built-in handlers:
-`ConsoleHandler` - (default)
-`FileHandler`
#### Custom message format
If you want to override default format of message you can define `formatter` option for handler. It can be either simple string-based format that uses `LogRecord` fields or more complicated function-based one that takes `LogRecord` as argument and outputs string.
Eg.
```ts
await log.setup({
handlers: {
stringFmt: new log.handlers.ConsoleHandler("DEBUG", {
formatter: "[{levelName}] {msg}"
}),
functionFmt: new log.handlers.ConsoleHandler("DEBUG", {
formatter: logRecord => {
let msg = `{logRecord.level} {logRecord.msg}`;
logRecord.args.forEach((arg, index) => {
msg += `, arg{index}: {arg}`;
});
return msg;
}
}),
},
loggers: {
default: {
level: "DEBUG",
handlers: ["stringFmt", "functionFmt"],
},
}
})
// calling
log.debug("Hello, world!", 1, "two", [3, 4, 5]);
// results in:
[DEBUG] Hello, world! // output from "stringFmt" handler