182 lines
5.7 KiB
Markdown
182 lines
5.7 KiB
Markdown
|
---
|
||
|
sidebar_position: 2
|
||
|
title: "2"
|
||
|
description: "Logging Specification v2"
|
||
|
---
|
||
|
|
||
|
# Version 2
|
||
|
This document aims to outline a unified specification, inspired by various logging implementations.
|
||
|
|
||
|
|
||
|
## Cross-language considerations
|
||
|
### Casing
|
||
|
This specification assumes that methods are written in CamelCase and enums in CONSTANT_CASE. If the programming language your implementation uses has different conventions, use them instead.
|
||
|
### Enums
|
||
|
This specification assumes that the programming language your implementation uses supports enums. If it doesn't, use integer constants instead. If that isn't possible, use strings.
|
||
|
|
||
|
|
||
|
## What a good logger needs
|
||
|
A good logger implementation needs the following things:
|
||
|
- levels, to distinguish message importance
|
||
|
- a message's origin, to know from where a message came
|
||
|
- the actual log message
|
||
|
|
||
|
|
||
|
## Levels
|
||
|
An implementation must provide at least five log levels and may implement an optional one to be able to determine a message's priority.
|
||
|
|
||
|
<table>
|
||
|
<tr>
|
||
|
<th>Name</th>
|
||
|
<th>Method name</th>
|
||
|
<th>Printed name</th>
|
||
|
<th>Enum name</th>
|
||
|
<th>Optional</th>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<th>Diagnostic</th>
|
||
|
<th><code>diag</code></th>
|
||
|
<th><code>DIAG</code></th>
|
||
|
<th><code>DIAGNOSTIC</code></th>
|
||
|
<th>No</th>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<th>Verbose</th>
|
||
|
<th><code>verb</code></th>
|
||
|
<th><code>VERB</code></th>
|
||
|
<th><code>VERBOSE</code></th>
|
||
|
<th>No</th>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<th>Silent Warning</th>
|
||
|
<th><code>sarn</code></th>
|
||
|
<th><code>SARN</code></th>
|
||
|
<th><code>SILENT_WARNING</code></th>
|
||
|
<th>No</th>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<th>Informational</th>
|
||
|
<th><code>info</code></th>
|
||
|
<th><code>INFO</code></th>
|
||
|
<th><code>INFORMATIONAL</code></th>
|
||
|
<th>No</th>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<th>Warning</th>
|
||
|
<th><code>warn</code></th>
|
||
|
<th><code>WARN</code></th>
|
||
|
<th><code>WARNING</code></th>
|
||
|
<th>No</th>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<th>Error</th>
|
||
|
<th><code>error</code></th>
|
||
|
<th><code>ERR!</code></th>
|
||
|
<th><code>ERROR</code></th>
|
||
|
<th>No</th>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<th>Crash</th>
|
||
|
<th><code>crash</code></th>
|
||
|
<th><code>CRSH</code></th>
|
||
|
<th><code>CRASH</code></th>
|
||
|
<th>If the language and/or platform does not provide a good native crash handler</th>
|
||
|
</tr>
|
||
|
</table>
|
||
|
|
||
|
|
||
|
## Format
|
||
|
A format is required to represent a log message as well as relevant information in a human way.
|
||
|
The logging format shall be minimal but extensible with so-called "format features",
|
||
|
which may be chained together. A few optional and required features are listed in this
|
||
|
specification. Implementation-specific features may be added, depending on the use case,
|
||
|
environment, language and other variables.
|
||
|
|
||
|
### Default format
|
||
|
`[<printed level name> <origin>] <message>`
|
||
|
|
||
|
### Feature `formatting`
|
||
|
The content stays the same but the message is colorized.
|
||
|
|
||
|
This feature is optional.
|
||
|
|
||
|
### Feature `runtime`
|
||
|
Prepends the time the implementation or application is running in milliseconds. \
|
||
|
Example by extending the default: `[<run time in milliseconds>ms] [<printed level name> <origin>] <message>`
|
||
|
|
||
|
This feature is required.
|
||
|
|
||
|
### Features `date` & `time`
|
||
|
Prepends the date and/or the time to the output. \
|
||
|
Example by extending the default: `[<date> [time]] [<printed level name> <origin>] <message>`
|
||
|
|
||
|
This feature is required unless the language of the implementation does not provide good support for dates and time.
|
||
|
|
||
|
### Features `methodName` & `lineNumber`
|
||
|
Appends the method name and/or line number to the origin.
|
||
|
Example by extending the default: `[<printed level name> <origin>#<method name>~<line number>] <message>`
|
||
|
|
||
|
This feature is required unless the language of the implementation does not provide insufficient or any automatic (ie. without developer intervention on log call) support.
|
||
|
|
||
|
### All features
|
||
|
Below is an example of how the format would look like if all features mentioned in this specification were enabled.
|
||
|
#### With placeholders
|
||
|
`[<runtime>ms] [<date> <time>] [<printed level name> <origin>#<method name>~<line number>] <message>`
|
||
|
#### Filled
|
||
|
`[505ms] [03.10.1990 23:23:23] [INFO Test.example#sayHi~42] Hello World!`
|
||
|
|
||
|
|
||
|
## Configuration
|
||
|
A logger implementing this specification should be able to
|
||
|
be configured by the running application at runtime.
|
||
|
This specification lists a few required and optional features.
|
||
|
Implementations may provide their own.
|
||
|
|
||
|
### Minimum level
|
||
|
Specifies the minimum allowed log level.
|
||
|
Lower levels are forbidden and won't be logged.
|
||
|
|
||
|
This option is required and must either be an enum, integer or a string (fallback to the next if one is unavailable).
|
||
|
|
||
|
### Features
|
||
|
Specifies a list of enabled features.
|
||
|
|
||
|
This option is required and must be a comma-separated string or list of strings.
|
||
|
|
||
|
### Multithreading
|
||
|
Specifies that the implementation is multithreaded by accepting
|
||
|
log calls, queueing and then processing them on a separate thread.
|
||
|
|
||
|
This option is optional but recommended.
|
||
|
|
||
|
### Thread Polling Delay
|
||
|
Specifies the time the logging thread shall
|
||
|
wait before processing the queue again.
|
||
|
This value should be subtracted by the
|
||
|
time if took to process all queued messages
|
||
|
after all messages have been processed.
|
||
|
|
||
|
This option is required if multithreading
|
||
|
is built into the implementation.
|
||
|
|
||
|
|
||
|
## Placeholders
|
||
|
Implementations may allow placeholders to be placed
|
||
|
into a log message and replaced during processing.
|
||
|
These must be wrapped inside `%`-signs and must
|
||
|
allow for optional configuration. Placeholders must
|
||
|
allow placeholders to be added and removed dynamically.
|
||
|
|
||
|
|
||
|
## Methods
|
||
|
Implementations are required to provide
|
||
|
methods for all levels, with each being
|
||
|
named after the level's method name.
|
||
|
|
||
|
Each method must require at least the message
|
||
|
to be logged. If required by the language of
|
||
|
the implementation, information about the
|
||
|
message origin may be required as well.
|
||
|
This however should be avoided to not annoy
|
||
|
developers and create maintenance burdens.
|