You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+78-93Lines changed: 78 additions & 93 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,35 +8,20 @@
8
8
9
9
# Discussion: Compositional Loggers
10
10
11
-
LoggingExtras is designs around allowing you to build arbitrarily complicated
12
-
systems for "log plumbing". That is to say basically routing logged information to different places.
13
-
It is built around the idea of simple parts which are composed together,
14
-
to allow for powerful and flexible definition of your logging system.
15
-
Without you having to define any custom loggers by subtyping `AbstractLogger`.
16
-
When we talk about composability we mean to say that the composition of any set of Loggers is itself a Logger.
17
-
LoggingExtras is a composable logging system.
18
-
19
-
Loggers can be broken down into 4 types:
20
-
-*Sinks*: Sinks are the final end point of a log messages journey. They write it to file, or display it on the console, or set off a red flashing light in the laboratory. A Sink should never decide what to accept, only what to do with it.
21
-
-*Filters*: Filters wrap around other loggers and decide whether or not to pass on a message. They can further be broken down by when that decision occurs (See `ActiveFilteredLogger` vs `EarlyFilteredLogger`).
22
-
-*Transformers*: Transformers modify the content of log messages, before passing them on. This includes the metadata like severity level. Unlike Filters they can't block a log message, but they could drop its level down to say `Debug` so that normally noone would see it.
23
-
-*Demux*: There is only one possible Demux Logger. and it is central to log routing. It acts as a hub that receives 1 log message, and then sends copies of it to all its child loggers. Like in the diagram above, it can be composed with Filters to control what goes where.
24
-
25
-
This is a basically full taxonomy of all compositional loggers.
26
-
This package implements the full set. So you shouldn't need to build your own routing components, just configure the ones included in this package.
27
-
28
-
It is worth understanding the idea of logging purity.
29
-
The loggers defined in this package are all pure.
30
-
The Filters, only filter, the Sinks only sink, the transformers only Transform.
31
-
32
-
We can contrast this to the the `ConsoleLogger` (the standard logger in the REPL).
33
-
The `ConsoleLogger` is an impure sink.
34
-
As well as displaying logs to the user (as a Sink);
35
-
it uses the log content, in the form of the `max_log` kwarg to decide if a log should be displayed (Active Filtering);
36
-
and it has a min_enabled_level setting, that controls if it will accept a message at all
37
-
(Early Filtering, in particular see `MinLevelLogger`).
38
-
If it was to be defined in a compositional way,
39
-
we would write something along the lines of:
11
+
LoggingExtras allows routing logged information to different places when constructing complicated "log plumbing" systems. Built upon the concept of simple parts composed together, subtyping `AbstractLogger` provides a powerful and flexible definition for your logging system without a need to define any custom loggers. When we talk about composability, the composition of any set of Loggers is itself a Logger, and LoggingExtras is a composable logging system.
12
+
13
+
Loggers break down into four types:
14
+
-*Sinks*: Sinks are the endpoint of a log message journey. They write it to file or display it on the console or set off a red flashing light in the laboratory. A Sink should never decide what to accept, only what to do with it.
15
+
-*Filters*: Filters wrap around other loggers and decide whether or not to pass on a message. When that decision occurs, they can be further broken down (See `ActiveFilteredLogger` vs `EarlyFilteredLogger`).
16
+
-*Transformers*: Transformers modify the content of log messages before passing them on, including metadata, such as severity level. Unlike Filters, they can't block a log message, but they could drop its level down to say Debug so that usually no one would see it.
17
+
-*Demux*: There is only one possible Demux Logger, and it is central to log routing. It acts as a hub that receives one log message and then sends copies to all its child loggers. Like in the diagram above, it can be composed with Filters to control what goes where.
18
+
19
+
This is a complete taxonomy of all compositional loggers, with this package implementing the entire set. As such, there should be no need to build routing components when configuring the ones included in this package.
20
+
21
+
It is worth understanding the idea of logging purity. The loggers defined in this package are all pure. The Filters only filter, the Sinks only sink, and the transformers only Transform.
22
+
23
+
We can contrast this to the `ConsoleLogger` (the standard logger in the REPL). The `ConsoleLogger` is an impure sink. As well as displaying logs to the user (as a Sink); it uses the log content, in the form of the `max_log`, to decide whether to display a log (Active Filtering); and it has a min_enabled_level setting that controls if it will accept a message at all (Early Filtering, in particular, see `MinLevelLogger`).
24
+
If defined in a compositional way, we would write something along the lines of:
The user implicitly controls when the files will be rolled over based on the `DateFormat` given.
346
-
To post-process the newly rotated file pass `rotation_callback::Function` as a keyword argument.
329
+
The user implicitly controls when the files are rolled over based on the `DateFormat` given.
330
+
To post-process the newly rotated file, pass `rotation_callback::Function` as a keyword argument.
347
331
See the docstring with (`?DatetimeRotatingFileLogger` in the REPL) for more details.
348
332
349
-
To control the logging output it is possible to pass a formatter function as the first argument
350
-
in the constructor. See `FormatLogger` for the requirements on the formatter function.
333
+
To control the logging output, passing a formatter function as the first argument in the constructor
334
+
is possible. See FormatLogger for the requirements on the formatter function.
351
335
352
336
## `FormatLogger` (*Sink*)
353
-
The `FormatLogger` is a sink that formats the message and prints to a wrapped IO.
354
-
Formatting is done by providing a function `f(io::IO, log_args::NamedTuple)`.
337
+
The `FormatLogger` is a sink that formats the message and prints it to a wrapped IO
338
+
with formatting provided by providing a function `f(io::IO, log_args::NamedTuple)`.
355
339
356
-
`FormatLogger` can take as its second argument either a writeable `IO` or a filepath. The `append::Bool` keyword
357
-
argument determines whether the file is opened in append mode (`"a"`) or truncate mode (`"w"`).
340
+
`FormatLogger` can take either a writeable `IO` or a filepath as its second argument. The `append::Bool` keyword
341
+
argument determines whether to open the file in append mode (`"a"`) or truncate mode (`"w"`).
358
342
359
343
```julia
360
344
julia>using LoggingExtras
@@ -378,9 +362,10 @@ Main | [Warn] This is a warning, should take a look.
378
362
## `LevelOverrideLogger` (*Filter*)
379
363
Allows overriding the minimum log level set by the logger it wraps.
380
364
Useful when debug logging
381
-
and used in conjuction with `Logging.with_logger` or `LoggingExtras.withlevel` to
365
+
and used in conjunction with `Logging.with_logger` or `LoggingExtras.withlevel` to
382
366
temporarily modify the current logger with a custom level.
383
-
More generally useful if you want to use the current/global logger as a _sink_ but don't know if it is going to have a problematically high min log level set (as julia's default logger sets min level to `Info`).
367
+
More generally applicable if you want to use the current/global logger as a _sink_
368
+
but don't know if it will have a problematically high min log level set (as julia's default logger sets min level to `Info`).
384
369
385
370
```julia
386
371
julia>using LoggingExtras
@@ -395,24 +380,24 @@ julia> with_logger(logger) do
395
380
```
396
381
This is roughly complementary to the `MinLevelFilterLogger`.
397
382
The `MinLevelFilterLogger` lets you effectively *raise* the level of any logger it wraps to meet the level you specify.
398
-
The `LevelOverrideLogger` lets you *lower* (or *raise*) the level of the wrapped logger as it bypasses checks on it entirely.
383
+
The `LevelOverrideLogger` enables you to *lower* (or *raise*) the level of the wrapped logger as it bypasses checks on it entirely.
399
384
400
385
# Utilities
401
386
402
387
## Verbosity macros
403
-
Sometimes when logging, it is desirable to be able to specify a verbosity level along with
404
-
the log level, and to be able to filter on verbosity levels. For example, you may want multiple levels
405
-
of verbosity for `Debug` log statements. LoggingExtras.jl exports verbosity macros that act like their
406
-
non-verbose counterparts, but allow specifying a verbosity level as well:
388
+
Sometimes when logging, it is desirable to specify a verbosity level along with
389
+
the log level and to be able to filter on verbosity levels. For example, you may want multiple
390
+
verbosity levels for `Debug` log statements. LoggingExtras.jl exports verbosity macros that act like their
391
+
non-verbose counterparts but allow specifying a verbosity level as well:
407
392
* `@debugv N msg`
408
393
* `@infov N msg`
409
394
* `@warnv N msg`
410
395
* `@errorv N msg`
411
396
412
-
For verbosity filtering, the `LoggingExtras.withlevel(f, Info; verbosity=0)` utlility is provided
413
-
for temporarily (i.e. while `f()` is executed) allowing log messages with `level` and `verbosity`.
414
-
This is very handy for allowing finergrained control in debug logging for long-running or complex user API function
415
-
calls. For example:
397
+
For verbosity filtering, the `LoggingExtras.withlevel(f, Info; verbosity=0)` utility is provided,
398
+
temporarily (i.e. while `f()` is executed) allowing log messages with `level` and `verbosity`.
399
+
This is very handy for allowing finer-grained debug logging control for long-running or complex user API function calls.
0 commit comments