1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
# Log
## Usage
```ts
import * as log from "https://deno.land/std/log/mod.ts";
// simple default logger, you can customize it
// by overriding logger and handler named "default"
log.debug("Hello world");
log.info("Hello world");
log.warning("Hello world");
log.error("Hello world");
log.critical("500 Internal server error");
// custom configuration
await log.setup({
handlers: {
console: new log.handlers.ConsoleHandler("DEBUG"),
file: new log.handlers.FileHandler("WARNING", {
filename: "./log.txt",
// you can change format of output message
formatter: "{levelName} {msg}"
})
},
loggers: {
// configure default logger available via short-hand methods above
default: {
level: "DEBUG",
handlers: ["console", "file"]
},
tasks: {
level: "ERROR",
handlers: ["console"]
}
}
});
let logger;
// get default logger
logger = log.getLogger();
logger.debug("fizz"); // logs to `console`, because `file` handler requires "WARNING" level
logger.warning("buzz"); // logs to both `console` and `file` handlers
// get custom logger
logger = log.getLogger("tasks");
logger.debug("fizz"); // won't get output becase this logger has "ERROR" level
logger.error("buzz"); // 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
unknownLogger = log.getLogger("mystery");
unknownLogger.info("foobar"); // no-op
```
## Advanced usage
### Loggers
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
10 Hello, world!, arg0: 1, arg1: two, arg3: [3, 4, 5] // output from "functionFmt" formatter
```
#### 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`.
|