From 66734c215d16552ceda2d12a0b1aea17fee5ef42 Mon Sep 17 00:00:00 2001 From: Chris Foster Date: Sat, 25 Feb 2017 00:51:31 +1000 Subject: [PATCH 1/8] Logging julep - initial WIP This is an attempt to write down some desired features of a julian logging API, without referring to a particular implementation strategy. --- Logging.md | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 1 + 2 files changed, 114 insertions(+) create mode 100644 Logging.md diff --git a/Logging.md b/Logging.md new file mode 100644 index 0000000..b8399a7 --- /dev/null +++ b/Logging.md @@ -0,0 +1,113 @@ +# JULEP Logging + +- **Title:** A unified logging interface +- **Author:** Chris Foster +- **Created:** February 2017 +- **Status:** work in progress + +## Abstract + +Production systems need robust and consistent logging; casual users want logging +to be as simple as `println()`. The logging interface in Base should support +both these needs in a simple, flexible and efficient way. + +In particular, this proposal seeks to: +* Encourage package authors to include logging by keeping usage simple but + making it efficient and convenient. +* Add a minimum number of features and concepts required to support log + filtering, formatting, and dispatch in production environments. +* Unify logging under a common interface to avoid inconsistency of logging + configuration and handling between packages. + +## Desirable features + +The desirable features fit into three rough categories - simplicity, flexibility +and efficiency. + +Logging should be **simple to use** so that package authors can reach for `info` +rather than `println()`. We should have: + +* A minimum of syntax - ideally just a logger verb and the message in most + cases. Context information for log messages (file name, line number, module, + stack trace, etc.) should be automatically gathered without a syntax burden. +* Freedom in formatting the log message - simple string interpolation, + `@sprintf` and `fmt()`, etc should all be fine. +* Zero logger setup for simple uses. +* Easy filtering of log messages. +* Clear guidelines about the meaning and appropriate use of standard log levels + for consistency between packages, along with guiding the appropriate use of + logging vs stdout. +* To encourage the use of logging over ad hoc console output, the default + console log handler should emphasize the *log message*, and metadata should be + printed in a non-intrusive way. + + +The API should be **flexible enough** for advanced users: + +* For all packages using the standard logging API, it should be simple to + intercept, filter and redirect logs in a unified and centrally controlled way. +* Log records are more than a string: loggers typically gather context + information both lexically (eg, module, file name, line number) and + dynamically (eg, time, stack trace, thread id). The API should preserve this + structured information, perhaps as a LogRecord type. +* Formatting and dispatch of log records should be in the hands of the user if + they need it. For example, a log handler library may need to write json + records across the network to a log server. +* It should be possible to log to a user defined log context; automatically + choosing a context for zero setup logging may not suit all cases. For + example, in some cases we may want to use a log context explicitly attached to + a user-defined data structure. +* Possible extensions + * User supplied `key=value` pairs for additional log context? + * Support for user defined log levels? + * Unique message IDs based on code location for finer grained message + filtering? + +The design should allow for an **efficient implementation**, to encourage +the availability of logging in production systems; logs you don't see should be +almost free, and logs you do see should be cheap to produce. The runtime cost +comes in three flavours: + +* Cost in the logging library, to determine whether to filter a message. +* Cost in user code, to construct quantities which will only be used in the + log message. +* Cost in the logging library in collecting context information and + to dispatch and format log records. + + +## Proposed design + +A rough work in progress implementation is available at +https://github.com/c42f/MicroLogging.jl + + +## Concrete use cases + +### Base + +In Base, there are three somewhat disparate mechanisms for controlling logging. +An improved logging interface should unify these in a way which is convenient +both in the code and for user control. + +* The 0.6 logging system's `logging()` function with redirection based on module + and function. +* The `DEBUG_LOADING` mechanism in loading.jl and `JULIA_DEBUG_LOADING` + environment variable. +* The depwarn system, and `--depwarn` command line flag + + +## Survey of other logging systems + +Much of the above is a reinterpretation in julia of python's standard logging +module, attempting to be even more convenient and much more efficient, while +retaining the same flexibility. + +* A summary of how this all fits in with Logging.jl, MiniLogging.jl, Memento.jl, + LumberJack.jl, and any other logging libraries which can be found. +* glib - https://developer.gnome.org/glib/stable/glib-Message-Logging.html +* Lager - https://github.com/erlang-lager/lager +* Some java logger *cough*? That should be enterprisey enough, right ;-) +* syslog ? + +TODO - much more here. + diff --git a/README.md b/README.md index c1f879d..02c9be8 100644 --- a/README.md +++ b/README.md @@ -6,3 +6,4 @@ It contains the following "Juleps" (Julia Enhancement Proposals): - [Pkg3](Pkg3.md) – the next generation of Julia package management - [RTLIB](RTLIB.md) – a runtime-library for Julia. - [Find](Find.md) - Reorganize search and find API +- [Logging](Logging.md) – A general logging interface From fdae06634f009f1aa083ec3011cd41d8402a06a8 Mon Sep 17 00:00:00 2001 From: Chris Foster Date: Mon, 3 Apr 2017 08:20:06 +1000 Subject: [PATCH 2/8] Mention threads and structured logging --- Logging.md | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/Logging.md b/Logging.md index b8399a7..712a7a4 100644 --- a/Logging.md +++ b/Logging.md @@ -39,7 +39,7 @@ rather than `println()`. We should have: logging vs stdout. * To encourage the use of logging over ad hoc console output, the default console log handler should emphasize the *log message*, and metadata should be - printed in a non-intrusive way. + communicated in a non-intrusive way. The API should be **flexible enough** for advanced users: @@ -49,7 +49,10 @@ The API should be **flexible enough** for advanced users: * Log records are more than a string: loggers typically gather context information both lexically (eg, module, file name, line number) and dynamically (eg, time, stack trace, thread id). The API should preserve this - structured information, perhaps as a LogRecord type. + structured information. +* Users should be able to add structured information to log records, to be + preserved along with data extracted from the logging context. For example, a + list of `key=value` pairs offers a decent combination of simplicity and power. * Formatting and dispatch of log records should be in the hands of the user if they need it. For example, a log handler library may need to write json records across the network to a log server. @@ -57,9 +60,8 @@ The API should be **flexible enough** for advanced users: choosing a context for zero setup logging may not suit all cases. For example, in some cases we may want to use a log context explicitly attached to a user-defined data structure. +* It should be possible to control log filtering per thread or task. * Possible extensions - * User supplied `key=value` pairs for additional log context? - * Support for user defined log levels? * Unique message IDs based on code location for finer grained message filtering? @@ -104,10 +106,11 @@ retaining the same flexibility. * A summary of how this all fits in with Logging.jl, MiniLogging.jl, Memento.jl, LumberJack.jl, and any other logging libraries which can be found. -* glib - https://developer.gnome.org/glib/stable/glib-Message-Logging.html -* Lager - https://github.com/erlang-lager/lager +* glib (C) - https://developer.gnome.org/glib/stable/glib-Message-Logging.html +* a-cl-logger (Common lisp) - https://github.com/AccelerationNet/a-cl-logger +* Lager (Erlang) - https://github.com/erlang-lager/lager * Some java logger *cough*? That should be enterprisey enough, right ;-) -* syslog ? +* syslog (unix) ? TODO - much more here. From cc73d4af44ae84ad680bfcd4a9d0c45d9eff2f4e Mon Sep 17 00:00:00 2001 From: Chris Foster Date: Thu, 22 Jun 2017 16:05:49 -0700 Subject: [PATCH 3/8] Rewrite abstract --- Logging.md | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/Logging.md b/Logging.md index 712a7a4..6ad806a 100644 --- a/Logging.md +++ b/Logging.md @@ -7,17 +7,32 @@ ## Abstract -Production systems need robust and consistent logging; casual users want logging -to be as simple as `println()`. The logging interface in Base should support -both these needs in a simple, flexible and efficient way. - -In particular, this proposal seeks to: -* Encourage package authors to include logging by keeping usage simple but - making it efficient and convenient. -* Add a minimum number of features and concepts required to support log - filtering, formatting, and dispatch in production environments. -* Unify logging under a common interface to avoid inconsistency of logging - configuration and handling between packages. +*Logging* is a tool for understanding program execution by recording the order and +timing of a sequence of events. A *logging library* provides tools to define +these events in the source code and capture the event stream when the program runs. +The information captured from each event makes its way through the system as a +*log record*. The ideal logging library should give developers and users insight +into the running of their software by provide tools to filter, save and +visualize these records. + +Julia has included simple logging in `Base` since version 0.1, but the tools to +generate and capture events are still immature as of version 0.6. For example, +log messages are unstructured, there's no systematic capture of log metadata, no +debug logging, inflexible dispatch and filtering, and the role of the code at +the log site isn't completely clear. Because of this, Julia 0.6 packages use +any of several incompatible logging libraries, and there's no systematic way to +generate and capture log messages. + +This julep aims to improve the situation by proposing: + +* A simple, unified interface to generate log events in `Base` +* Conventions for the structure and semantics of the resulting log records +* A minimum of dispatch machinery to capture, route and filter log records +* A default backend for displaying, filtering and interacting with the log + stream which makes the log record structure visible. + +A non-goal is to create a complete set of logging backends - these can be +supplied by packages. ## Desirable features From a0df6d44f45b831865943a78f55a9a8b34f07b84 Mon Sep 17 00:00:00 2001 From: Chris Foster Date: Thu, 22 Jun 2017 17:45:29 -0700 Subject: [PATCH 4/8] Start describing proposed implementation * Quickstart for frontend * What is a log record? * Some work on inspiration section --- Logging.md | 122 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 106 insertions(+), 16 deletions(-) diff --git a/Logging.md b/Logging.md index 6ad806a..a21e9bd 100644 --- a/Logging.md +++ b/Logging.md @@ -47,14 +47,15 @@ rather than `println()`. We should have: stack trace, etc.) should be automatically gathered without a syntax burden. * Freedom in formatting the log message - simple string interpolation, `@sprintf` and `fmt()`, etc should all be fine. -* Zero logger setup for simple uses. +* No mention of log dispatch should be necessary at the message creation site. * Easy filtering of log messages. * Clear guidelines about the meaning and appropriate use of standard log levels for consistency between packages, along with guiding the appropriate use of logging vs stdout. -* To encourage the use of logging over ad hoc console output, the default - console log handler should emphasize the *log message*, and metadata should be - communicated in a non-intrusive way. +* The default console log handler should integrate somehow with the display + system to show log records in a way which is highly readable. Ideally logging + should be a tool for package authors just as much as it is a tool for + understanding production systems. The API should be **flexible enough** for advanced users: @@ -94,8 +95,82 @@ comes in three flavours: ## Proposed design -A rough work in progress implementation is available at -https://github.com/c42f/MicroLogging.jl +A prototype implementation is available at https://github.com/c42f/MicroLogging.jl +### Quickstart Example + +#### Frontend +```julia +# using Base.Log + +# Logging macros +@debug "A message for debugging (filtered out by default)" +@info "Information about normal program operation" +@warn "A potentially problem was detected" +@error "Something definitely went wrong, but we recovered enough to continue" +@logmsg Log.Info "Explicitly defined info log level" + +# Free form message formatting +x = 10.50 +@info "$x" +@info @sprintf("%.3f", x) +@info begin + A = ones(4,4) + "sum(A) = $(sum(A))" +end + +# Progress reporting +for i=1:10 + @info "Some algorithm" progress=i/10 +end + +# User defined key value pairs +foo_val = 10.0 +@info "test" foo=foo_val bar=42 +``` + + +### What is a log record? + +Logging statements are used to understand algorithm flow - the order and timing +in which logging events happen - and the program state at each event. Each +logging event is preserved in a **log record**. The information in a record +needs to be gathered efficiently, but should be rich enough to give insight into +program execution. + +A log record includes information explicitly given at the call site, and any +relevant metadata which can be harvested from the lexical and dynamic +environment. Most logging libraries allow for two key pieces of information +to be supplied explicitly: + +* The **log message** - a user-defined string containing key pieces of program + state, chosen by the developer. +* The **log level** - a category for the message, usually ordered from verbose + to severe. The log level is generally used as an initial filter to remove + verbose messages. + +Some logging libraries (for example +[glib](https://developer.gnome.org/glib/stable/glib-Message-Logging.html) +structured logging) allow users to supply extra log record information in the +form of key value pairs. Others like +[log4j2](https://logging.apache.org/log4j/2.x/manual/messages.html) require extra information to be +explicitly wrapped in a log record type. In julia, supporting key value pairs +in logging statements gives a good mixture of usability and flexibility: +Information can be communicated to the logging backend as simple keyword +function arguments, and the keywords provide syntactic hints for early filtering +in the logging macro frontend. + +In addition to the explicitly provided information, some useful metadata can be +automatically extracted and stored with each log record. Some of this is +extracted from the lexical environment or generated by the logging frontend +macro, including code location (module, file, line number) and a unique message +identifier. The rest is dynamic state which can generally on demand by the +backend, including system time, stack trace, current task id. + +### The logging frontend + +### Dispatching records + +### Early filtering ## Concrete use cases @@ -113,19 +188,34 @@ both in the code and for user control. * The depwarn system, and `--depwarn` command line flag -## Survey of other logging systems +## Inspriation -Much of the above is a reinterpretation in julia of python's standard logging -module, attempting to be even more convenient and much more efficient, while -retaining the same flexibility. +This Julep draws inspiration from many previous logging frameworks, and helpful +discussions with many people online and at JuliaCon 2017. -* A summary of how this all fits in with Logging.jl, MiniLogging.jl, Memento.jl, - LumberJack.jl, and any other logging libraries which can be found. -* glib (C) - https://developer.gnome.org/glib/stable/glib-Message-Logging.html +The Java logging framework [log4j2](https://logging.apache.org/log4j/2.x/) was a +great source of use cases, as it contains the lessons from at least twenty years +of large production systems. While containing a fairly large amount of +complexity, the design is generally very well motivated in the documentation, +giving a rich set of use cases. The julia logging libraries - Base in julia 0.6, +Logging.jl, MiniLogging.jl, LumberJack.jl, and particularly +[Memento.jl](https://github.com/invenia/Memento.jl) - provided helpful +context for the needs of the julia community. + +Structured logging as available in +[glib](https://developer.gnome.org/glib/stable/glib-Message-Logging.html) +and [RFC5424](https://datatracker.ietf.org/doc/rfc5424/?include_text=1) (The +Syslog protocol) provide context for the usefulness of log records as key value +pairs. + +For the most part, existing julia libraries seem to follow the design tradition +of the standard [python logging library](https://docs.python.org/3/library/logging.html), +which has a lineage further described in [PEP-282](https://www.python.org/dev/peps/pep-0282/). +The python logging system provided a starting point for this Julep, though the +design eventually diverged from the typical hierarchical setup. + +TODO: Re-survey the following? * a-cl-logger (Common lisp) - https://github.com/AccelerationNet/a-cl-logger * Lager (Erlang) - https://github.com/erlang-lager/lager -* Some java logger *cough*? That should be enterprisey enough, right ;-) -* syslog (unix) ? -TODO - much more here. From a4f2f97f688959cea7c3850cd32b621cdf0316ad Mon Sep 17 00:00:00 2001 From: Chris Foster Date: Fri, 23 Jun 2017 00:38:55 -0700 Subject: [PATCH 5/8] Minor fixes --- Logging.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Logging.md b/Logging.md index a21e9bd..7985957 100644 --- a/Logging.md +++ b/Logging.md @@ -168,10 +168,19 @@ backend, including system time, stack trace, current task id. ### The logging frontend -### Dispatching records +TODO + +### Logging middle layer + +TODO ### Early filtering +TODO + +### Default backend + +TODO ## Concrete use cases @@ -188,7 +197,7 @@ both in the code and for user control. * The depwarn system, and `--depwarn` command line flag -## Inspriation +## Inspiration This Julep draws inspiration from many previous logging frameworks, and helpful discussions with many people online and at JuliaCon 2017. From 39a5769d6e821531b3502d5d6d343f9f25610ff5 Mon Sep 17 00:00:00 2001 From: Chris Foster Date: Fri, 23 Jun 2017 09:01:36 -0700 Subject: [PATCH 6/8] Fix typo --- Logging.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Logging.md b/Logging.md index 7985957..c074632 100644 --- a/Logging.md +++ b/Logging.md @@ -163,7 +163,7 @@ In addition to the explicitly provided information, some useful metadata can be automatically extracted and stored with each log record. Some of this is extracted from the lexical environment or generated by the logging frontend macro, including code location (module, file, line number) and a unique message -identifier. The rest is dynamic state which can generally on demand by the +identifier. The rest is dynamic state which can generated on demand by the backend, including system time, stack trace, current task id. ### The logging frontend From e27d6d32e253aa791aca99e11d28dd35f2ce80ad Mon Sep 17 00:00:00 2001 From: Chris Foster Date: Fri, 23 Jun 2017 21:49:01 -0700 Subject: [PATCH 7/8] Refactor section describing the tension in the design problem --- Logging.md | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/Logging.md b/Logging.md index c074632..5b9ad3c 100644 --- a/Logging.md +++ b/Logging.md @@ -34,17 +34,21 @@ This julep aims to improve the situation by proposing: A non-goal is to create a complete set of logging backends - these can be supplied by packages. -## Desirable features +## The design problem - two competing users -The desirable features fit into three rough categories - simplicity, flexibility -and efficiency. +The core of the logging design problem is the competing desires of two sets of +users: package authors versus application authors. -Logging should be **simple to use** so that package authors can reach for `info` -rather than `println()`. We should have: +### The package author -* A minimum of syntax - ideally just a logger verb and the message in most - cases. Context information for log messages (file name, line number, module, - stack trace, etc.) should be automatically gathered without a syntax burden. +The package author wants logging with the default setup to "just work": it +should involve **zero setup** and should produce **output which is easy to +understand**. + +* A minimum of syntax - ideally just a logger verb and the message object in + many cases. Context information for log messages (file name, line number, + module, stack trace, etc.) should be automatically gathered without a syntax + burden. * Freedom in formatting the log message - simple string interpolation, `@sprintf` and `fmt()`, etc should all be fine. * No mention of log dispatch should be necessary at the message creation site. @@ -53,10 +57,10 @@ rather than `println()`. We should have: for consistency between packages, along with guiding the appropriate use of logging vs stdout. * The default console log handler should integrate somehow with the display - system to show log records in a way which is highly readable. Ideally logging - should be a tool for package authors just as much as it is a tool for - understanding production systems. + system to show log records in a way which is highly readable. + +### The application author The API should be **flexible enough** for advanced users: From 070ab4f0204602451e699762ab3ba6080e0d7569 Mon Sep 17 00:00:00 2001 From: Chris Foster Date: Sun, 17 Sep 2017 11:24:03 +1000 Subject: [PATCH 8/8] More refactoring of the background section. --- Logging.md | 118 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 68 insertions(+), 50 deletions(-) diff --git a/Logging.md b/Logging.md index 5b9ad3c..0a454f2 100644 --- a/Logging.md +++ b/Logging.md @@ -28,78 +28,95 @@ This julep aims to improve the situation by proposing: * A simple, unified interface to generate log events in `Base` * Conventions for the structure and semantics of the resulting log records * A minimum of dispatch machinery to capture, route and filter log records -* A default backend for displaying, filtering and interacting with the log - stream which makes the log record structure visible. +* A default backend for displaying, filtering and interacting with the log stream. A non-goal is to create a complete set of logging backends - these can be supplied by packages. -## The design problem - two competing users +## The design problem -The core of the logging design problem is the competing desires of two sets of -users: package authors versus application authors. +There's two broad classes of users for a logging library - library authors and +application authors - each with rather different needs. -### The package author +### The library author -The package author wants logging with the default setup to "just work": it -should involve **zero setup** and should produce **output which is easy to -understand**. +Ideally logging should be a high value tool for library development, making +library authors lives easier, and giving users insight. + +For the library author, the logging tools should make log events *easy to generate*: + +* Logging should require a minimum of syntax - ideally just a logger verb and + the message object in many cases. Context information for log messages (file + name, line number, module, stack trace, etc.) should be automatically gathered + without a syntax burden. +* Log generation should be free from prescriptive log message formatting. Simple + string interpolation, `@sprintf` and `fmt()`, etc should all be fine. When + log messages aren't strings, a sensible conversion should be applied by + default. +* Flexible user definable structure for log records should make it easy to + record snapshots of program state in the form of variable names and values. + This would generalize `@show` using log records as a transport mechanism. + +The default configuration for log message reporting should involve *zero +setup* and should produce *readable output*: -* A minimum of syntax - ideally just a logger verb and the message object in - many cases. Context information for log messages (file name, line number, - module, stack trace, etc.) should be automatically gathered without a syntax - burden. -* Freedom in formatting the log message - simple string interpolation, - `@sprintf` and `fmt()`, etc should all be fine. * No mention of log dispatch should be necessary at the message creation site. -* Easy filtering of log messages. -* Clear guidelines about the meaning and appropriate use of standard log levels - for consistency between packages, along with guiding the appropriate use of - logging vs stdout. * The default console log handler should integrate somehow with the display - system to show log records in a way which is highly readable. + system, to show log records in a way which is highly readable. +* Basic filtering of log messages should be easy to configure. +The default configuration for log message reporting will generally define what +library authors see during development, so will end up defining the conventions +authors use when including logging in their library. To this extent, it's +important to do a good job displaying metadata! ### The application author -The API should be **flexible enough** for advanced users: +Application authors bring together many disparate libraries into a larger +system; they need consistency and flexibility in collecting log records. + +Log events are generally tagged with useful context information which is +available both lexically (eg, module, file name, line number) and dynamically +(eg, time, stack trace, thread id). Log records should have *consistent, +flexible metadata* which represents and preserve this structured information in +a way that can be collected systematically. -* For all packages using the standard logging API, it should be simple to - intercept, filter and redirect logs in a unified and centrally controlled way. -* Log records are more than a string: loggers typically gather context - information both lexically (eg, module, file name, line number) and - dynamically (eg, time, stack trace, thread id). The API should preserve this - structured information. +* Each logging location should have a unique identifier, `id`, passed as part of + the log record metadata. This greatly simplifies tasks such limiting the rate + of logging for a given line of code. * Users should be able to add structured information to log records, to be preserved along with data extracted from the logging context. For example, a list of `key=value` pairs offers a decent combination of simplicity and power. -* Formatting and dispatch of log records should be in the hands of the user if - they need it. For example, a log handler library may need to write json - records across the network to a log server. -* It should be possible to log to a user defined log context; automatically - choosing a context for zero setup logging may not suit all cases. For - example, in some cases we may want to use a log context explicitly attached to - a user-defined data structure. -* It should be possible to control log filtering per thread or task. -* Possible extensions - * Unique message IDs based on code location for finer grained message - filtering? - -The design should allow for an **efficient implementation**, to encourage +* Clear guidelines should be given about the meaning and appropriate use of + standard log levels so libraries can be consistent. + +Log *collection* should be unified: + +* For all libraries using the standard logging API, it should be simple to + intercept, and dispatch logs in a unified way which is under the control of + the application author. For example, to write json log records across the + network to a log server. +* It should be possible to naturally control log dispatch from concurrent tasks. + For example, if the application uses a library to handle simultaneous HTTP + connections for both an important task and a noncritical background job, we + may wish to handle the messages generated by these two `Task`s differently. + +The design should allow for an *efficient implementation*, to encourage the availability of logging in production systems; logs you don't see should be almost free, and logs you do see should be cheap to produce. The runtime cost -comes in three flavours: +comes in a few flavours: -* Cost in the logging library, to determine whether to filter a message. -* Cost in user code, to construct quantities which will only be used in the +* Cost in the logging frontend, to determine whether to filter a message. +* Cost in the logging frontend, in collecting context information. +* Cost in user code, to construct quantities which will only be used in a log message. -* Cost in the logging library in collecting context information and - to dispatch and format log records. +* Cost in the logging backend, in filtering and displaying messages. ## Proposed design A prototype implementation is available at https://github.com/c42f/MicroLogging.jl + ### Quickstart Example #### Frontend @@ -111,7 +128,7 @@ A prototype implementation is available at https://github.com/c42f/MicroLogging. @info "Information about normal program operation" @warn "A potentially problem was detected" @error "Something definitely went wrong, but we recovered enough to continue" -@logmsg Log.Info "Explicitly defined info log level" +@logmsg Logging.Info "Explicitly defined info log level" # Free form message formatting x = 10.50 @@ -132,12 +149,13 @@ foo_val = 10.0 @info "test" foo=foo_val bar=42 ``` +#### Backend ### What is a log record? Logging statements are used to understand algorithm flow - the order and timing in which logging events happen - and the program state at each event. Each -logging event is preserved in a **log record**. The information in a record +logging event is preserved in a *log record*. The information in a record needs to be gathered efficiently, but should be rich enough to give insight into program execution. @@ -146,9 +164,9 @@ relevant metadata which can be harvested from the lexical and dynamic environment. Most logging libraries allow for two key pieces of information to be supplied explicitly: -* The **log message** - a user-defined string containing key pieces of program +* The *log message* - a user-defined string containing key pieces of program state, chosen by the developer. -* The **log level** - a category for the message, usually ordered from verbose +* The *log level* - a category for the message, usually ordered from verbose to severe. The log level is generally used as an initial filter to remove verbose messages. @@ -167,7 +185,7 @@ In addition to the explicitly provided information, some useful metadata can be automatically extracted and stored with each log record. Some of this is extracted from the lexical environment or generated by the logging frontend macro, including code location (module, file, line number) and a unique message -identifier. The rest is dynamic state which can generated on demand by the +identifier. The rest is dynamic state which can be generated on demand by the backend, including system time, stack trace, current task id. ### The logging frontend