[READ-ONLY] Mirror of https://github.com/FoxxMD/logging. A typed, opinionated, batteries-included, Pino-based logging solution for backend TS/JS projects
foxxmd.github.io/logging
child-logger
logging
logging-library
nodejs
pinojs
typescript-library
1<!DOCTYPE html><html class="default" lang="en"><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>@foxxmd/logging Docs</title><meta name="description" content="Documentation for @foxxmd/logging Docs"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="assets/style.css"/><link rel="stylesheet" href="assets/highlight.css"/><script defer src="assets/main.js"></script><script async src="assets/icons.js" id="tsd-icons-script"></script><script async src="assets/search.js" id="tsd-search-script"></script><script async src="assets/navigation.js" id="tsd-nav-script"></script><script defer data-domain="foxxmd.github.io" src="https://plausible.foxxmd.dev/js/script.js"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><div class="table-cell" id="tsd-search" data-base="."><div class="field"><label for="tsd-search-field" class="tsd-widget tsd-toolbar-icon search no-caption"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="assets/icons.svg#icon-search"></use></svg></label><input type="text" id="tsd-search-field" aria-label="Search"/></div><div class="field"><div id="tsd-toolbar-links"><a href="http://foxxmd.github.io/logging">Docs</a><a href="https://github.com/foxxmd/logging">GitHub</a></div></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="index.html" class="title">@foxxmd/logging Docs</a></div><div class="table-cell" id="tsd-widgets"><a href="#" class="tsd-widget tsd-toolbar-icon menu no-caption" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><h2>@foxxmd/logging Docs</h2></div><div class="tsd-panel tsd-typography"><a id="md:foxxmdlogging" class="tsd-anchor"></a><h1 class="tsd-anchor-link">@foxxmd/logging<a href="#md:foxxmdlogging" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h1><p><a href="https://github.com/FoxxMD/logging/releases" target="_blank" class="external"><img src="https://img.shields.io/github/v/release/foxxmd/logging" alt="Latest Release"></a>
2<a href="https://www.npmjs.com/package/@foxxmd/logging" target="_blank" class="external"><img src="https://img.shields.io/npm/v/%40foxxmd%2Flogging" alt="NPM Version"></a>
3<a href="https://npm.runkit.com/%40foxxmd%2Flogging" target="_blank" class="external"><img src="https://img.shields.io/static/v1?label=Try%20it%20online%20on&message=RunKit&color=f55fa6" alt="Try on Runkit"></a>
4<a href="https://opensource.org/licenses/MIT" target="_blank" class="external"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a></p>
5<p>A typed, opinionated, batteries-included, <a href="https://getpino.io" target="_blank" class="external">Pino</a>-based logging solution for backend TS/JS projects.</p>
6<p>Features:</p>
7<ul>
8<li>Fully typed for Typescript projects</li>
9<li>One-line, <a href="#md:quick-start">turn-key logging</a> to console and rotating file</li>
10<li><a href="#md:child-loggers">Child (nested) loggers</a> with hierarchical label prefixes for log messages</li>
11<li>Per-destination level filtering configurable via ENV or arguments</li>
12<li>Clean, opinionated log output format powered by <a href="https://github.com/pinojs/pino-pretty" target="_blank" class="external">pino-pretty</a>:
13<ul>
14<li>Colorized output when stream is TTY and supports it</li>
15<li>Automatically <a href="#md:serializing-objects-and-errors">serialize passed objects and Errors</a>, including <a href="https://github.com/tc39/proposal-error-cause" target="_blank" class="external">Error Cause</a></li>
16<li>Automatically redact current working directory from log output</li>
17</ul>
18</li>
19<li><a href="#md:additional-app-logger-configuration">Bring-Your-Own settings</a>
20<ul>
21<li>Add or use your own streams/<a href="https://getpino.io/#/docs/transports?id=known-transports" target="_blank" class="external">transports</a> for destinations</li>
22<li>All pino-pretty configs are exposed and extensible</li>
23</ul>
24</li>
25<li><a href="#md:building-a-logger">Build-Your-Own Logger</a>
26<ul>
27<li>Don't want to use any of the pre-built transports? Leverage the convenience of @foxxmd/logging wrappers and default settings but build your logger from scratch</li>
28</ul>
29</li>
30</ul>
31<img src="media://example.svg" alt="example log output">
32<p><strong>Documentation best viewed on <a href="https://foxxmd.github.io/logging" target="_blank" class="external">https://foxxmd.github.io/logging</a></strong></p>
33<a id="md:install" class="tsd-anchor"></a><h1 class="tsd-anchor-link">Install<a href="#md:install" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h1><pre><code><span class="hl-0">npm</span><span class="hl-1"> </span><span class="hl-0">install</span><span class="hl-1"> @</span><span class="hl-0">foxxmd</span><span class="hl-1">/</span><span class="hl-0">logging</span>
34</code><button>Copy</button></pre>
35
36<a id="md:quick-start" class="tsd-anchor"></a><h1 class="tsd-anchor-link">Quick Start<a href="#md:quick-start" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h1><pre><code class="ts"><span class="hl-2">import</span><span class="hl-1"> { </span><span class="hl-0">loggerAppRolling</span><span class="hl-1">, </span><span class="hl-0">loggerApp</span><span class="hl-1"> } </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-3">"@foxxmd/logging"</span><span class="hl-1">;</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">logger</span><span class="hl-1"> = </span><span class="hl-6">loggerApp</span><span class="hl-1">();</span><br/><span class="hl-0">logger</span><span class="hl-1">.</span><span class="hl-6">info</span><span class="hl-1">(</span><span class="hl-3">'Test'</span><span class="hl-1">);</span><br/><span class="hl-7">/*</span><br/><span class="hl-7"> * Logs to -> console, colorized</span><br/><span class="hl-7"> * Logs to -> CWD/logs/app.log</span><br/><span class="hl-7"> * </span><br/><span class="hl-7"> * [2024-03-07 10:31:34.963 -0500] DEBUG: Test</span><br/><span class="hl-7"> * */</span><br/><br/><br/><span class="hl-7">// or for rolling log files we need to scan logs dir before opening a file</span><br/><span class="hl-7">// and need to await initial logger</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">rollingLogger</span><span class="hl-1"> = </span><span class="hl-2">await</span><span class="hl-1"> </span><span class="hl-6">loggerAppRolling</span><span class="hl-1">();</span><br/><span class="hl-0">rollingLogger</span><span class="hl-1">.</span><span class="hl-6">info</span><span class="hl-1">(</span><span class="hl-3">'Test'</span><span class="hl-1">);</span><br/><span class="hl-7">/*</span><br/><span class="hl-7"> * Logs to -> console, colorized</span><br/><span class="hl-7"> * Logs to daily log file, max 10MB size -> CWD/logs/app.1.log</span><br/><span class="hl-7"> * </span><br/><span class="hl-7"> * [2024-03-07 10:31:34.963 -0500] DEBUG: Test</span><br/><span class="hl-7"> * */</span>
37</code><button type="button">Copy</button></pre>
38
39<a id="md:loggers" class="tsd-anchor"></a><h1 class="tsd-anchor-link">Loggers<a href="#md:loggers" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h1><p>The package exports 4 top-level loggers.</p>
40<a id="md:app-loggers" class="tsd-anchor"></a><h3 class="tsd-anchor-link">App Loggers<a href="#md:app-loggers" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>These are the loggers that should be used for the majority of your application. They accept an optional configuration object for configuring log destinations.</p>
41<ul>
42<li><a href="https://foxxmd.github.io/logging/functions/index.loggerApp.html" target="_blank" class="external"><code>loggerApp</code></a> - Logs to console and a fixed file destination</li>
43<li><a href="https://foxxmd.github.io/logging/functions/index.loggerAppRolling.html" target="_blank" class="external"><code>loggerAppRolling</code></a> - Logs to console and a rolling file destination</li>
44</ul>
45<a id="md:helper-loggers" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Helper Loggers<a href="#md:helper-loggers" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>These loggers are pre-defined for specific use cases:</p>
46<ul>
47<li><a href="https://foxxmd.github.io/logging/variables/index.loggerTrace.html" target="_blank" class="external"><code>loggerTrace</code></a> - Logs to console at the lowest minimum level, <code>trace</code>. Can be used during application startup before a logger app configuration has been parsed.</li>
48<li><a href="https://foxxmd.github.io/logging/variables/index.loggerDebug.html" target="_blank" class="external"><code>loggerDebug</code></a> - Logs ONLY to console at minimum <code>debug</code> level. Can be used during application startup before a logger app configuration has been parsed.</li>
49<li><a href="https://foxxmd.github.io/logging/variables/index.loggerTest.html" target="_blank" class="external"><code>loggerTest</code></a> - A noop logger (will not log anywhere) for use in tests/mockups.</li>
50</ul>
51<a id="md:configuring" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Configuring<a href="#md:configuring" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p>The <a href="#md:app-loggers">App Loggers</a> take an optional <a href="https://foxxmd.github.io/logging/interfaces/index.LogOptions.html" target="_blank" class="external"><code>LogOptions</code></a> to configure <a href="https://foxxmd.github.io/logging/types/index.LogLevel.html" target="_blank" class="external"><code>LogLevel</code></a> globally or individually for <strong>Console</strong> and <strong>File</strong> outputs. <a href="https://foxxmd.github.io/logging/interfaces/index.FileLogOptions.html" target="_blank" class="external"><code>file</code> in <code>LogOptions</code></a> may also be an object that specifies more behavior for log file output.</p>
52<pre><code class="ts"><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">infoLogger</span><span class="hl-1"> = </span><span class="hl-6">loggerApp</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-0">level:</span><span class="hl-1"> </span><span class="hl-3">'info'</span><span class="hl-1"> </span><span class="hl-7">// console and file will log any levels `info` and above</span><br/><span class="hl-1">});</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">logger</span><span class="hl-1"> = </span><span class="hl-6">loggerApp</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-0">console:</span><span class="hl-1"> </span><span class="hl-3">'debug'</span><span class="hl-1">, </span><span class="hl-7">// console will log `debug` and higher</span><br/><span class="hl-1"> </span><span class="hl-0">file:</span><span class="hl-1"> </span><span class="hl-3">'warn'</span><span class="hl-1"> </span><span class="hl-7">// file will log `warn` and higher</span><br/><span class="hl-1">});</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">fileLogger</span><span class="hl-1"> = </span><span class="hl-6">loggerRollingApp</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-7">// no level specified => console defaults to `info` level</span><br/><span class="hl-1"> </span><span class="hl-0">file:</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-0">level:</span><span class="hl-1"> </span><span class="hl-3">'warn'</span><span class="hl-1">, </span><span class="hl-7">// file will log `warn` and higher</span><br/><span class="hl-1"> </span><span class="hl-0">path:</span><span class="hl-1"> </span><span class="hl-3">'/my/cool/path/output.log'</span><span class="hl-1">, </span><span class="hl-7">// output to log file at this path</span><br/><span class="hl-1"> </span><span class="hl-0">frequency:</span><span class="hl-1"> </span><span class="hl-3">'daily'</span><span class="hl-1">, </span><span class="hl-7">// rotate hourly</span><br/><span class="hl-1"> </span><span class="hl-0">size:</span><span class="hl-1"> </span><span class="hl-3">'20MB'</span><span class="hl-1">, </span><span class="hl-7">// rotate if file size grows larger than 20MB</span><br/><span class="hl-1"> </span><span class="hl-0">timestamp:</span><span class="hl-1"> </span><span class="hl-3">'unix'</span><span class="hl-1"> </span><span class="hl-7">// use unix epoch timestamp instead of iso8601 in rolling file</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">});</span>
53</code><button type="button">Copy</button></pre>
54
55<p>An optional second parameter, <a href="https://foxxmd.github.io/logging/interfaces/index.LoggerAppExtras.html" target="_blank" class="external"><code>LoggerAppExtras</code></a>, may be passed that allows adding additional log destinations or pino-pretty customization to the <a href="#md:app-loggers">App Loggers</a>. Some defaults and convenience variables for pino-pretty options are also available in <a href="(https://foxxmd.github.io/logging/modules/factory.html)" target="_blank" class="external"><code>@foxxmd/logging/factory</code></a> prefixed with <code>PRETTY_</code>.</p>
56<p>An example using <code>LoggerAppExtras</code>:</p>
57<pre><code class="ts"><span class="hl-2">import</span><span class="hl-1"> { </span><span class="hl-0">loggerApp</span><span class="hl-1"> } </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-3">'@foxxmd/logging'</span><span class="hl-1">;</span><br/><span class="hl-2">import</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-0">PRETTY_ISO8601</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-0">buildDestinationFile</span><span class="hl-1"> </span><br/><span class="hl-1">} </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-3">"@foxxmd/logging/factory"</span><span class="hl-1">;</span><br/><br/><span class="hl-7">// additional file logging but only at `warn` or higher</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">warnFileDestination</span><span class="hl-1"> = </span><span class="hl-6">buildDestinationFile</span><span class="hl-1">(</span><span class="hl-3">'warn'</span><span class="hl-1">, {</span><span class="hl-0">path:</span><span class="hl-1"> </span><span class="hl-3">'./myLogs/warn.log'</span><span class="hl-1">});</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">logger</span><span class="hl-1"> = </span><span class="hl-6">loggerApp</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-0">level:</span><span class="hl-1"> </span><span class="hl-3">'debug'</span><span class="hl-1">, </span><span class="hl-7">// console AND built-in file logging will log `debug` and higher</span><br/><span class="hl-1"> }, {</span><br/><span class="hl-1"> </span><span class="hl-0">destinations:</span><span class="hl-1"> [</span><span class="hl-0">warnFileDestination</span><span class="hl-1">],</span><br/><span class="hl-1"> </span><span class="hl-0">pretty:</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-0">translateTime:</span><span class="hl-1"> </span><span class="hl-5">PRETTY_ISO8601</span><span class="hl-1"> </span><span class="hl-7">// replaces standard timestamp with ISO8601 format</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">});</span><br/><span class="hl-0">logger</span><span class="hl-1">.</span><span class="hl-6">debug</span><span class="hl-1">(</span><span class="hl-3">'Test'</span><span class="hl-1">);</span><br/><span class="hl-7">// [2024-03-07T11:27:41-05:00] DEBUG: Test</span>
58</code><button type="button">Copy</button></pre>
59
60<p>See <a href="#md:building-a-logger">Building A Logger</a> for more information.</p>
61<a id="md:colorizing-docker-logs" class="tsd-anchor"></a><h4 class="tsd-anchor-link">Colorizing Docker Logs<a href="#md:colorizing-docker-logs" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h4><p>Color output to STD out/err is normally automatically detected by <a href="https://github.com/jorgebucaran/colorette" target="_blank" class="external">colorette</a> or can manually be set using <code>colorize</code> anywhere <a href="https://foxxmd.github.io/logging/interfaces/factory._internal_.PrettyOptions_.html" target="_blank" class="external">PrettyOptions</a> are accepted. However docker output can be hard to detect as supporting colorizing, or the output may not be TTY at the container interface but is viewed by a terminal or web app that does support colorizing.</p>
62<p>Therefore <code>@foxxmd/logging</code> will look for a <code>COLORED_STD</code> environmental variable and, if no other <code>colorize</code> option is set <em>and the ENV is not empty</em>, will use the truthy value of this variable to set <code>colorize</code> <strong>for any <code>buildDestinationStdout</code> or <code>buildDestinationStderr</code> transports.</strong> This includes the built-in stdout transports for <code>loggerApp</code> and <code>loggerAppRolling</code>.</p>
63<p>Thus you could set <code>COLORED_STD=true</code> in your Dockerfile to coerce colored output to docker logs. If a user does not want colored output for any reason they can simply override the environmental variable like <code>COLORED_STD=false</code></p>
64<a id="md:usage" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Usage<a href="#md:usage" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><a id="md:child-loggers" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Child Loggers<a href="#md:child-loggers" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p><a href="https://getpino.io/#/docs/child-loggers" target="_blank" class="external">Pino Child loggers</a> can be created using the <a href="https://foxxmd.github.io/logging/functions/index.childLogger.html" target="_blank" class="external"><code>childLogger</code></a> function with the added ability to inherit <strong>Labels</strong> from their parent loggers.</p>
65<p><strong>Labels</strong> are inserted between the log level and message contents of a log. The child logger inherits <strong>all</strong> labels from <strong>all</strong> its parent loggers.</p>
66<p><code>childLogger</code> accepts a single string/function label or an array of string/function labels.</p>
67<pre><code class="ts"><span class="hl-2">import</span><span class="hl-1"> {</span><span class="hl-0">loggerApp</span><span class="hl-1">, </span><span class="hl-0">childLogger</span><span class="hl-1">} </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-3">'@foxxmd/logging'</span><span class="hl-1">;</span><br/><br/><span class="hl-0">logger</span><span class="hl-1"> = </span><span class="hl-6">loggerApp</span><span class="hl-1">();</span><br/><span class="hl-0">logger</span><span class="hl-1">.</span><span class="hl-6">debug</span><span class="hl-1">(</span><span class="hl-3">'Test'</span><span class="hl-1">);</span><br/><span class="hl-7">// [2024-03-07 11:27:41.944 -0500] DEBUG: Test</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">nestedChild1</span><span class="hl-1"> = </span><span class="hl-6">childLogger</span><span class="hl-1">(</span><span class="hl-0">logger</span><span class="hl-1">, </span><span class="hl-3">'First'</span><span class="hl-1">);</span><br/><span class="hl-0">nestedChild1</span><span class="hl-1">.</span><span class="hl-6">debug</span><span class="hl-1">(</span><span class="hl-3">'I am nested one level'</span><span class="hl-1">);</span><br/><span class="hl-7">// [2024-03-07 11:27:41.945 -0500] DEBUG: [First] I am nested one level</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">nestedChild2</span><span class="hl-1"> = </span><span class="hl-6">childLogger</span><span class="hl-1">(</span><span class="hl-0">nestedChild1</span><span class="hl-1">, [</span><span class="hl-3">'Second'</span><span class="hl-1">, () </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-3">'Third'</span><span class="hl-1">]);</span><br/><span class="hl-0">nestedChild2</span><span class="hl-1">.</span><span class="hl-6">warn</span><span class="hl-1">(</span><span class="hl-3">'I am nested two levels but with more labels'</span><span class="hl-1">);</span><br/><span class="hl-7">// [2024-03-07 11:27:41.945 -0500] WARN: [First] [Second] [Third] I am nested two levels but with more labels</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">siblingLogger</span><span class="hl-1"> = </span><span class="hl-6">childLogger</span><span class="hl-1">(</span><span class="hl-0">logger</span><span class="hl-1">, [</span><span class="hl-3">'1Sib'</span><span class="hl-1">,</span><span class="hl-3">'2Sib'</span><span class="hl-1">]);</span><br/><span class="hl-0">siblingLogger</span><span class="hl-1">.</span><span class="hl-6">info</span><span class="hl-1">(</span><span class="hl-3">'Test'</span><span class="hl-1">);</span><br/><span class="hl-7">// [2024-03-07 11:27:41.945 -0500] INFO: [1Sib] [2Sib] Test</span>
68</code><button type="button">Copy</button></pre>
69
70<p>Labels can also be added at "runtime" by passing an object with <code>labels</code> prop to the logger level function. These labels will be appended to any existing labels on the logger.</p>
71<pre><code class="ts"><span class="hl-0">logger</span><span class="hl-1">.</span><span class="hl-6">debug</span><span class="hl-1">({</span><span class="hl-0">labels:</span><span class="hl-1"> [</span><span class="hl-3">'MyLabel'</span><span class="hl-1">]}, </span><span class="hl-3">'My log message'</span><span class="hl-1">);</span>
72</code><button type="button">Copy</button></pre>
73
74<p><strong>NOTE:</strong> If a label <em>function</em> throws an error then the label will be the error's message. Make sure your labels don't throw!</p>
75<a id="md:filtering-by-label" class="tsd-anchor"></a><h4 class="tsd-anchor-link">Filtering By Label<a href="#md:filtering-by-label" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h4><p>Logs can be filtered by labels similar to how <a href="https://github.com/debug-js/debug" target="_blank" class="external">debug-js</a> works.</p>
76<p>By default <em>no</em> filtering is done. Your child loggers follow the Pino Child Logger behavior of inherting parent log level.</p>
77<p>Using either <code>LOG_FILTER_ENABLE</code> or <code>LOG_FILTER_DISABLE</code> you can enable or disable a child logger and it's children.</p>
78<pre><code class="ts"><br/><span class="hl-7">/*</span><br/><span class="hl-7"> * process.env.LOG_FILTER_ENABLE = 'Third:Fourth,Second:*:Foo,Bar'</span><br/><span class="hl-7"> */</span><br/><br/><span class="hl-2">import</span><span class="hl-1"> {</span><span class="hl-0">loggerApp</span><span class="hl-1">, </span><span class="hl-0">childLogger</span><span class="hl-1">} </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-3">'@foxxmd/logging'</span><span class="hl-1">;</span><br/><br/><span class="hl-0">logger</span><span class="hl-1"> = </span><span class="hl-6">loggerApp</span><span class="hl-1">();</span><br/><span class="hl-0">logger</span><span class="hl-1">.</span><span class="hl-6">debug</span><span class="hl-1">(</span><span class="hl-3">'Test'</span><span class="hl-1">);</span><br/><span class="hl-7">// [2024-03-07 11:27:41.944 -0500] DEBUG: Test</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">nestedChild1</span><span class="hl-1"> = </span><span class="hl-6">childLogger</span><span class="hl-1">(</span><span class="hl-0">logger</span><span class="hl-1">, </span><span class="hl-3">'First'</span><span class="hl-1">);</span><br/><span class="hl-0">nestedChild1</span><span class="hl-1">.</span><span class="hl-6">debug</span><span class="hl-1">(</span><span class="hl-3">'I am nested one level'</span><span class="hl-1">);</span><br/><span class="hl-7">// [2024-03-07 11:27:41.945 -0500] DEBUG: [First] I am nested one level</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">nestedChild2</span><span class="hl-1"> = </span><span class="hl-6">childLogger</span><span class="hl-1">(</span><span class="hl-0">nestedChild1</span><span class="hl-1">, [</span><span class="hl-3">'Second'</span><span class="hl-1">, </span><span class="hl-3">'Third'</span><span class="hl-1">], { </span><span class="hl-0">level:</span><span class="hl-1"> </span><span class="hl-3">'silent'</span><span class="hl-1"> });</span><br/><span class="hl-0">nestedChild2</span><span class="hl-1">.</span><span class="hl-6">info</span><span class="hl-1">(</span><span class="hl-3">'I do not log because of set level and not enabled by filter'</span><span class="hl-1">);</span><br/><br/><span class="hl-7">// without LOG_FILTER_ENABLE from above set, the below logging would be silent</span><br/><span class="hl-7">// because they inherit the level from their parent</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">nestedChild3</span><span class="hl-1"> = </span><span class="hl-6">childLogger</span><span class="hl-1">(</span><span class="hl-0">nestedChild2</span><span class="hl-1">, [</span><span class="hl-3">'Fourth'</span><span class="hl-1">]);</span><br/><span class="hl-0">nestedChild3</span><span class="hl-1">.</span><span class="hl-6">info</span><span class="hl-1">(</span><span class="hl-3">'I do log because of filter Third:Fourth'</span><span class="hl-1">);</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">nestedChild4</span><span class="hl-1"> = </span><span class="hl-6">childLogger</span><span class="hl-1">(</span><span class="hl-0">nestedChild3</span><span class="hl-1">, [</span><span class="hl-3">'Foo'</span><span class="hl-1">]);</span><br/><span class="hl-0">nestedChild4</span><span class="hl-1">.</span><span class="hl-6">info</span><span class="hl-1">(</span><span class="hl-3">'I do log because of filter Second:*:Foo'</span><span class="hl-1">);</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">nestedChild5</span><span class="hl-1"> = </span><span class="hl-6">childLogger</span><span class="hl-1">(</span><span class="hl-0">nestedChild4</span><span class="hl-1">, [</span><span class="hl-3">'Bar'</span><span class="hl-1">]);</span><br/><span class="hl-0">nestedChild5</span><span class="hl-1">.</span><span class="hl-6">info</span><span class="hl-1">(</span><span class="hl-3">'I do log because of filter Bar'</span><span class="hl-1">);</span>
79</code><button type="button">Copy</button></pre>
80
81<p>The minimum level a child logger is "enabled" to is ENV <code>LOG_FILTER_ENABLE_LEVEL</code> or <code>trace</code>, by default. It can also be specified by passing <code>labelEnableLevel</code> to childLogger options.</p>
82<p>The minimum level a child logger is "disabled" to is ENV <code>LOG_FILTER_DISABLE_LEVEL</code> or <code>silent</code>, by default. It can also be specified by passing <code>labelDisableLevel</code> to childLogger options.</p>
83<p>There are also options for passing your own function to determine if a child logger should be enabled or disabled. See <a href="https://foxxmd.github.io/logging/functions/index.childLogger.html" target="_blank" class="external"><code>childLogger</code></a> docs for full a full reference.</p>
84<p>A caveat to be aware of: <strong>enable/disable by filter is evaluated once, when <code>childLogger</code> is instantiated.</strong> This means:</p>
85<ul>
86<li>Only the labels added by <code>childLogger</code> insantiation are applicable. Labels added during logging, IE <code>logger.info({labels: ['Runtime']}, "a log")</code>, are not considered.</li>
87<li>Labels that are functions are evaluated <strong>once</strong>, when <code>childLogger</code> is instantiated</li>
88<li>Changing the <code>LOG_FILTER_*</code> envs after a childLogger is created will have no effect on it</li>
89</ul>
90<a id="md:serializing-objects-and-errors" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Serializing Objects and Errors<a href="#md:serializing-objects-and-errors" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Passing an object or array as the first argument to the logger will cause the object to be JSONified and pretty printed below the log message</p>
91<pre><code class="ts"><span class="hl-0">logger</span><span class="hl-1">.</span><span class="hl-6">debug</span><span class="hl-1">({</span><span class="hl-0">myProp:</span><span class="hl-1"> </span><span class="hl-3">'a string'</span><span class="hl-1">, </span><span class="hl-0">nested:</span><span class="hl-1"> {</span><span class="hl-0">anotherProps:</span><span class="hl-1"> [</span><span class="hl-3">'val1'</span><span class="hl-1">, </span><span class="hl-3">'val2'</span><span class="hl-1">], </span><span class="hl-0">boolProp:</span><span class="hl-1"> </span><span class="hl-4">true</span><span class="hl-1">}}, </span><span class="hl-3">'Test'</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-7">/*</span><br/><span class="hl-7">[2024-03-07 11:39:37.687 -0500] DEBUG: Test</span><br/><span class="hl-7"> myProp: "a string"</span><br/><span class="hl-7"> nested: {</span><br/><span class="hl-7"> "anotherProps": [</span><br/><span class="hl-7"> "val1",</span><br/><span class="hl-7"> "val2"</span><br/><span class="hl-7"> ],</span><br/><span class="hl-7"> "boolProp": true</span><br/><span class="hl-7"> }</span><br/><span class="hl-7"> */</span>
92</code><button type="button">Copy</button></pre>
93
94<p>Passing an <code>Error</code> as the first argument will pretty print the error stack including any <a href="https://github.com/tc39/proposal-error-cause" target="_blank" class="external">causes.</a></p>
95<pre><code class="ts"><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">er</span><span class="hl-1"> = </span><span class="hl-4">new</span><span class="hl-1"> </span><span class="hl-6">Error</span><span class="hl-1">(</span><span class="hl-3">'This is the original error'</span><span class="hl-1">);</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">causeErr</span><span class="hl-1"> = </span><span class="hl-4">new</span><span class="hl-1"> </span><span class="hl-6">ErrorWithCause</span><span class="hl-1">(</span><span class="hl-3">'A top-level error'</span><span class="hl-1">, {</span><span class="hl-0">cause:</span><span class="hl-1"> </span><span class="hl-0">er</span><span class="hl-1">});</span><br/><span class="hl-0">logger</span><span class="hl-1">.</span><span class="hl-6">debug</span><span class="hl-1">(</span><span class="hl-0">causeErr</span><span class="hl-1">, </span><span class="hl-3">'Test'</span><span class="hl-1">);</span><br/><span class="hl-7">/*</span><br/><span class="hl-7">[2024-03-07 11:43:27.453 -0500] DEBUG: Test</span><br/><span class="hl-7">Error: A top-level error</span><br/><span class="hl-7"> at <anonymous> (/my/dir/src/index.ts:55:18)</span><br/><span class="hl-7">caused by: Error: This is the original error</span><br/><span class="hl-7"> at <anonymous> (/my/dir/src/index.ts:54:12)</span><br/><span class="hl-7"> */</span>
96</code><button type="button">Copy</button></pre>
97
98<p>Passing an <code>Error</code> without a second argument (message) will cause the top-level error's message to be printed instead of log message.</p>
99<a id="md:building-a-logger" class="tsd-anchor"></a><h1 class="tsd-anchor-link">Building A Logger<a href="#md:building-a-logger" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h1><p>All the functionality required to build your own logger is exported by <a href="https://foxxmd.github.io/logging/modules/factory.html" target="_blank" class="external"><code>@foxxmd/logging/factory</code></a>. You can customize almost every facet of logging.</p>
100<p>A logger is composed of a minimum default level and array of objects that implement <a href="https://foxxmd.github.io/logging/interfaces/index._internal_.StreamEntry-1.html" target="_blank" class="external"><code>StreamEntry</code></a>, the same interface used by <a href="https://getpino.io/#/docs/api?id=pino-multistream" target="_blank" class="external"><code>pino.multistream</code></a>. The only constraint is that your streams must accept the same levels as <code>@foxxmd/logging</code> using the <a href="https://foxxmd.github.io/logging/types/index.LogLevelStreamEntry.html" target="_blank" class="external"><code>LogLevelStreamEntry</code></a> interface that extends <code>StreamEntry</code>.</p>
101<pre><code class="ts"><span class="hl-2">import</span><span class="hl-1"> {</span><span class="hl-0">LogLevelStreamEntry</span><span class="hl-1">} </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-3">'@foxxmd/logging'</span><span class="hl-1">;</span><br/><span class="hl-2">import</span><span class="hl-1"> { </span><span class="hl-0">buildLogger</span><span class="hl-1"> } </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-3">"@foxxmd/logging/factory"</span><span class="hl-1">;</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">myStreams</span><span class="hl-1">: </span><span class="hl-8">LogLevelStreamEntry</span><span class="hl-1">[] = [];</span><br/><span class="hl-7">// build streams</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">logger</span><span class="hl-1"> = </span><span class="hl-6">buildLogger</span><span class="hl-1">(</span><span class="hl-3">'debug'</span><span class="hl-1">, </span><span class="hl-0">myStreams</span><span class="hl-1">);</span><br/><span class="hl-0">logger</span><span class="hl-1">.</span><span class="hl-6">debug</span><span class="hl-1">(</span><span class="hl-3">'Test'</span><span class="hl-1">);</span>
102</code><button type="button">Copy</button></pre>
103
104<p><code>factory</code> exports several "destination" <code>LogLevelStreamEntry</code> function creators with default configurations that can be overridden.</p>
105<pre><code class="ts"><span class="hl-2">import</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-0">buildLogger</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-0">buildDestinationStream</span><span class="hl-1">, </span><span class="hl-7">// generic NodeJS.WriteableStream or SonicBoom DestinationStream</span><br/><span class="hl-1"> </span><span class="hl-0">buildDestinationStdout</span><span class="hl-1">, </span><span class="hl-7">// stream to STDOUT</span><br/><span class="hl-1"> </span><span class="hl-0">buildDestinationStderr</span><span class="hl-1">, </span><span class="hl-7">// stream to STDERR</span><br/><span class="hl-1"> </span><span class="hl-0">buildDestinationFile</span><span class="hl-1">, </span><span class="hl-7">// write to static file</span><br/><span class="hl-1"> </span><span class="hl-0">buildDestinationRollingFile</span><span class="hl-1"> </span><span class="hl-7">// write to rolling file</span><br/><span class="hl-1">} </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-3">"@foxxmd/logging/factory"</span><span class="hl-1">;</span>
106</code><button type="button">Copy</button></pre>
107
108<p>All <code>buildDestination</code> functions take args:</p>
109<ul>
110<li><code>level</code> (first arg) - minimum level to log at</li>
111<li><code>options</code> (second arg) - an object extending <a href="https://github.com/pinojs/pino-pretty?tab=readme-ov-file#options" target="_blank" class="external"><code>pino-pretty</code> options</a>, <a href="https://foxxmd.github.io/logging/interfaces/factory._internal_.PrettyOptions_.html" target="_blank" class="external"><code>PrettyOptions</code></a></li>
112</ul>
113<p><code>options</code> inherits a default <code>pino-pretty</code> configuration that comprises <code>@foxxmd/logging</code>'s opinionated logging format. The common default config can be generated using <a href="https://foxxmd.github.io/logging/functions/factory.prettyOptsFactory.html" target="_blank" class="external"><code>prettyOptsFactory</code></a> which accepts an optional <code>PrettyOptions</code> object to override defaults:</p>
114<pre><code class="ts"><span class="hl-2">import</span><span class="hl-1"> { </span><span class="hl-0">prettyOptsFactory</span><span class="hl-1"> } </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-3">"@foxxmd/logging/factory"</span><span class="hl-1">;</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">defaultConfig</span><span class="hl-1"> = </span><span class="hl-6">prettyOptsFactory</span><span class="hl-1">();</span><br/><br/><span class="hl-7">// override with your own config</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">myCustomizedConfig</span><span class="hl-1"> = </span><span class="hl-6">prettyOptsFactory</span><span class="hl-1">({ </span><span class="hl-0">colorize:</span><span class="hl-1"> </span><span class="hl-4">false</span><span class="hl-1"> });</span>
115</code><button type="button">Copy</button></pre>
116
117<p>Pre-configured <code>PrettyOptions</code> are also provided for different destinations:</p>
118<pre><code class="ts"><span class="hl-2">import</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-0">PRETTY_OPTS_CONSOLE</span><span class="hl-1">, </span><span class="hl-7">// default config</span><br/><span class="hl-1"> </span><span class="hl-0">PRETTY_OPTS_FILE</span><span class="hl-1"> </span><span class="hl-7">// disables colorize</span><br/><span class="hl-1">} </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-3">"@foxxmd/logging/factory"</span><span class="hl-1">;</span>
119</code><button type="button">Copy</button></pre>
120
121<p>Specific buildDestinations also require passing a stream or path:</p>
122<p><a href="https://foxxmd.github.io/logging/functions/factory.buildDestinationStream.html" target="_blank" class="external"><code>buildDestinationStream</code></a> must pass a <code>NodeJS.WriteableStream</code> or SonicBoom <code>DestinationStream</code> to options as <a href="https://foxxmd.github.io/logging/types/factory.StreamDestination.html" target="_blank" class="external"><code>destination</code></a></p>
123<pre><code class="ts"><span class="hl-2">import</span><span class="hl-1"> {</span><span class="hl-0">buildDestinationStream</span><span class="hl-1">} </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-3">"@foxxmd/logging/factory"</span><span class="hl-1">;</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">myStream</span><span class="hl-1"> = </span><span class="hl-4">new</span><span class="hl-1"> </span><span class="hl-6">WritableStream</span><span class="hl-1">();</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">dest</span><span class="hl-1"> = </span><span class="hl-6">buildDestinationStream</span><span class="hl-1">(</span><span class="hl-3">'debug'</span><span class="hl-1">, {</span><span class="hl-0">destination:</span><span class="hl-1"> </span><span class="hl-0">myStream</span><span class="hl-1">});</span>
124</code><button type="button">Copy</button></pre>
125
126<p><a href="https://foxxmd.github.io/logging/functions/factory.buildDestinationStdout.html" target="_blank" class="external"><code>buildDestinationStdout</code></a> and <a href="https://foxxmd.github.io/logging/functions/factory.buildDestinationStderr.html" target="_blank" class="external"><code>buildDestinationStderr</code></a> do not require a destination as they are fixed to STDOUT/STDERR</p>
127<p><a href="https://foxxmd.github.io/logging/functions/factory.buildDestinationFile.html" target="_blank" class="external"><code>buildDestinationFile</code></a> and <a href="https://foxxmd.github.io/logging/functions/factory.buildDestinationRollingFile.html" target="_blank" class="external"><code>buildDestinationRollingFile</code></a> must pass a <a href="https://foxxmd.github.io/logging/types/factory.FileDestination.html" target="_blank" class="external"><code>path</code></a> to options</p>
128<pre><code class="ts"><span class="hl-2">import</span><span class="hl-1"> {</span><span class="hl-0">buildDestinationFile</span><span class="hl-1">} </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-3">"@foxxmd/logging/factory"</span><span class="hl-1">;</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">dest</span><span class="hl-1"> = </span><span class="hl-6">buildDestinationFile</span><span class="hl-1">(</span><span class="hl-3">'debug'</span><span class="hl-1">, {</span><span class="hl-0">path:</span><span class="hl-1"> </span><span class="hl-3">'/path/to/file.log'</span><span class="hl-1">});</span>
129</code><button type="button">Copy</button></pre>
130
131<a id="md:example" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Example<a href="#md:example" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Putting everything above together</p>
132<pre><code class="ts"><span class="hl-2">import</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-0">buildDestinationStream</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-0">buildDestinationFile</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-0">prettyOptsFactory</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-0">buildDestinationStdout</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-0">buildLogger</span><br/><span class="hl-1">} </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-3">"@foxxmd/logging/factory"</span><span class="hl-1">;</span><br/><span class="hl-2">import</span><span class="hl-1"> { </span><span class="hl-0">PassThrough</span><span class="hl-1"> } </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-3">"node:stream"</span><span class="hl-1">;</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">hookStream</span><span class="hl-1"> = </span><span class="hl-4">new</span><span class="hl-1"> </span><span class="hl-6">PassThrough</span><span class="hl-1">();</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">hookDestination</span><span class="hl-1"> = </span><span class="hl-6">buildDestinationStream</span><span class="hl-1">(</span><span class="hl-3">'debug'</span><span class="hl-1">, {</span><br/><span class="hl-1"> ...</span><span class="hl-6">prettyOptsFactory</span><span class="hl-1">({</span><span class="hl-0">sync:</span><span class="hl-1"> </span><span class="hl-4">true</span><span class="hl-1">, </span><span class="hl-0">ignore:</span><span class="hl-1"> </span><span class="hl-3">'pid'</span><span class="hl-1">}),</span><br/><span class="hl-1"> </span><span class="hl-0">destination:</span><span class="hl-1"> </span><span class="hl-0">hookStream</span><br/><span class="hl-1">});</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">debugFileDestination</span><span class="hl-1"> = </span><span class="hl-6">buildDestinationFile</span><span class="hl-1">(</span><span class="hl-3">'debug'</span><span class="hl-1">, {</span><span class="hl-0">path:</span><span class="hl-1"> </span><span class="hl-3">'./myLogs/debug.log'</span><span class="hl-1">});</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">warnFileDestination</span><span class="hl-1"> = </span><span class="hl-6">buildDestinationFile</span><span class="hl-1">(</span><span class="hl-3">'warn'</span><span class="hl-1">, {</span><span class="hl-0">path:</span><span class="hl-1"> </span><span class="hl-3">'./myLogs/warn.log'</span><span class="hl-1">});</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">logger</span><span class="hl-1"> = </span><span class="hl-6">buildLogger</span><span class="hl-1">(</span><span class="hl-3">'debug'</span><span class="hl-1">, [</span><br/><span class="hl-1"> </span><span class="hl-0">hookDestination</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-6">buildDestinationStdout</span><span class="hl-1">(</span><span class="hl-3">'debug'</span><span class="hl-1">),</span><br/><span class="hl-1"> </span><span class="hl-0">debugFileDestination</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-0">warnFileDestination</span><br/><span class="hl-1">]);</span><br/><span class="hl-0">hookStream</span><span class="hl-1">.</span><span class="hl-6">on</span><span class="hl-1">(</span><span class="hl-3">'data'</span><span class="hl-1">, (</span><span class="hl-0">log</span><span class="hl-1">) </span><span class="hl-4">=></span><span class="hl-1"> {</span><span class="hl-0">console</span><span class="hl-1">.</span><span class="hl-6">log</span><span class="hl-1">(</span><span class="hl-0">log</span><span class="hl-1">)});</span><br/><span class="hl-0">logger</span><span class="hl-1">.</span><span class="hl-6">debug</span><span class="hl-1">(</span><span class="hl-3">'Test'</span><span class="hl-1">)</span><br/><span class="hl-7">// logs to hookStream</span><br/><span class="hl-7">// logs to STDOUT</span><br/><span class="hl-7">// logs to file ./myLogs/debug.log</span><br/><span class="hl-7">// does NOT log to file ./myLogs/warn.log</span>
133</code><button type="button">Copy</button></pre>
134
135<a id="md:parsing-logoptions" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Parsing LogOptions<a href="#md:parsing-logoptions" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>If you wish to use <a href="#md:configuring"><code>LogOptions</code></a> to get default log levels for your destinations use <a href="https://foxxmd.github.io/logging/functions/index.parseLogOptions.html" target="_blank" class="external"><code>parseLogOptions</code></a>:</p>
136<pre><code class="ts"><span class="hl-2">import</span><span class="hl-1"> {</span><span class="hl-0">parseLogOptions</span><span class="hl-1">, </span><span class="hl-0">LogOptions</span><span class="hl-1">} </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-3">'@foxxmd/logging'</span><span class="hl-1">;</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">parsedOptions</span><span class="hl-1">: </span><span class="hl-8">LogOptions</span><span class="hl-1"> = </span><span class="hl-6">parseLogOptions</span><span class="hl-1">(</span><span class="hl-0">myConfig</span><span class="hl-1">);</span>
137</code><button type="button">Copy</button></pre>
138
139<a id="md:examples" class="tsd-anchor"></a><h1 class="tsd-anchor-link">Examples<a href="#md:examples" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h1><p>Various use-cases for <code>@foxxmd/logging</code> and how to configure a logger for them.</p>
140<p>Remember, <code>loggerApp</code> and <code>loggerAppRolling</code> <strong>accept the same arguments.</strong> The examples below use <code>loggerApp</code> but <code>loggerAppRolling</code> can be used as a drop-in replacement in order to use a rolling log file.</p>
141<a id="md:log-to-console-and-file" class="tsd-anchor"></a><h4 class="tsd-anchor-link">Log to Console and File<a href="#md:log-to-console-and-file" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h4><pre><code class="ts"><span class="hl-2">import</span><span class="hl-1"> {</span><span class="hl-0">loggerApp</span><span class="hl-1">, </span><span class="hl-0">loggerAppRolling</span><span class="hl-1">} </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-3">'@foxxmd/logging'</span><span class="hl-1">;</span><br/><br/><span class="hl-7">// static log file at ./logs/app.log</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">staticLogger</span><span class="hl-1"> = </span><span class="hl-6">loggerApp</span><span class="hl-1">();</span><br/><br/><span class="hl-7">// rolling log file at ./logs/app.1.log</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">rollingLogger</span><span class="hl-1"> = </span><span class="hl-6">loggerAppRolling</span><span class="hl-1">();</span>
142</code><button type="button">Copy</button></pre>
143
144<a id="md:log-at-specific-level-or-higher-for-console-and-file" class="tsd-anchor"></a><h4 class="tsd-anchor-link">Log At Specific Level Or Higher for Console and File<a href="#md:log-at-specific-level-or-higher-for-console-and-file" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h4><pre><code class="ts"><span class="hl-2">import</span><span class="hl-1"> {</span><span class="hl-0">loggerApp</span><span class="hl-1">} </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-3">'@foxxmd/logging'</span><span class="hl-1">;</span><br/><br/><span class="hl-7">// INFO is the default level</span><br/><span class="hl-7">// when 'console' is not specified it logs to 'info' or higher</span><br/><span class="hl-7">// when 'file' is not specified it logs to 'info' or higher</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">infoLogger</span><span class="hl-1"> = </span><span class="hl-6">loggerApp</span><span class="hl-1">();</span><br/><br/><span class="hl-7">// logs to console and log at 'debug' level and higher</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">debugLogger</span><span class="hl-1"> = </span><span class="hl-6">loggerApp</span><span class="hl-1">({</span><span class="hl-0">level:</span><span class="hl-1"> </span><span class="hl-3">'debug'</span><span class="hl-1">});</span>
145</code><button type="button">Copy</button></pre>
146
147<a id="md:log-at-debug-for-console-and-warn-for-file" class="tsd-anchor"></a><h4 class="tsd-anchor-link">Log At <code>debug</code> for Console and <code>warn</code> for File<a href="#md:log-at-debug-for-console-and-warn-for-file" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h4><pre><code class="ts"><span class="hl-2">import</span><span class="hl-1"> {</span><span class="hl-0">loggerApp</span><span class="hl-1">} </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-3">'@foxxmd/logging'</span><span class="hl-1">;</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">logger</span><span class="hl-1"> = </span><span class="hl-6">loggerApp</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-0">console:</span><span class="hl-1"> </span><span class="hl-3">'debug'</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-0">file:</span><span class="hl-1"> </span><span class="hl-3">'warn'</span><br/><span class="hl-1">});</span>
148</code><button type="button">Copy</button></pre>
149
150<a id="md:do-not-log-to-file" class="tsd-anchor"></a><h4 class="tsd-anchor-link">Do not log to File<a href="#md:do-not-log-to-file" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h4><pre><code class="ts"><span class="hl-2">import</span><span class="hl-1"> {</span><span class="hl-0">loggerApp</span><span class="hl-1">} </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-3">'@foxxmd/logging'</span><span class="hl-1">;</span><br/><br/><span class="hl-7">// also logs to console at 'info' level</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">logger</span><span class="hl-1"> = </span><span class="hl-6">loggerApp</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-0">file:</span><span class="hl-1"> </span><span class="hl-4">false</span><br/><span class="hl-1">});</span>
151</code><button type="button">Copy</button></pre>
152
153<a id="md:log-to-specific-file" class="tsd-anchor"></a><h4 class="tsd-anchor-link">Log to Specific File<a href="#md:log-to-specific-file" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h4><pre><code class="ts"><span class="hl-2">import</span><span class="hl-1"> {</span><span class="hl-0">loggerApp</span><span class="hl-1">} </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-3">'@foxxmd/logging'</span><span class="hl-1">;</span><br/><br/><span class="hl-7">// also logs to console at 'info' level</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">logger</span><span class="hl-1"> = </span><span class="hl-6">loggerApp</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-0">file:</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-0">path:</span><span class="hl-1"> </span><span class="hl-3">'./path/to/file.log'</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">});</span>
154</code><button type="button">Copy</button></pre>
155
156<a id="md:log-to-rolling-file-with-unix-timestamp" class="tsd-anchor"></a><h4 class="tsd-anchor-link">Log to Rolling File with Unix Timestamp<a href="#md:log-to-rolling-file-with-unix-timestamp" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h4><pre><code class="ts"><span class="hl-2">import</span><span class="hl-1"> {</span><span class="hl-0">loggerApp</span><span class="hl-1">} </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-3">'@foxxmd/logging'</span><span class="hl-1">;</span><br/><br/><span class="hl-7">// also logs to console at 'info' level</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">logger</span><span class="hl-1"> = </span><span class="hl-6">loggerApp</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-0">file:</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-0">timestamp:</span><span class="hl-1"> </span><span class="hl-3">'unix'</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">});</span>
157</code><button type="button">Copy</button></pre>
158
159<a id="md:log-to-rolling-file-with-no-timestamp" class="tsd-anchor"></a><h4 class="tsd-anchor-link">Log to Rolling File with no timestamp<a href="#md:log-to-rolling-file-with-no-timestamp" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h4><pre><code class="ts"><span class="hl-2">import</span><span class="hl-1"> {</span><span class="hl-0">loggerApp</span><span class="hl-1">} </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-3">'@foxxmd/logging'</span><span class="hl-1">;</span><br/><br/><span class="hl-7">// also logs to console at 'info' level</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">logger</span><span class="hl-1"> = </span><span class="hl-6">loggerApp</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-0">file:</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-7">// specify size but NOT 'frequency' to disable timestamps in filename</span><br/><span class="hl-1"> </span><span class="hl-0">size:</span><span class="hl-1"> </span><span class="hl-3">'10M'</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">});</span>
160</code><button type="button">Copy</button></pre>
161
162<a id="md:log-to-additional-file-for-error-only" class="tsd-anchor"></a><h4 class="tsd-anchor-link">Log to additional File for 'error' only<a href="#md:log-to-additional-file-for-error-only" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h4><pre><code class="ts"><span class="hl-2">import</span><span class="hl-1"> {</span><span class="hl-0">loggerApp</span><span class="hl-1">} </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-3">'@foxxmd/logging'</span><span class="hl-1">;</span><br/><span class="hl-2">import</span><span class="hl-1"> { </span><span class="hl-0">buildDestinationFile</span><span class="hl-1"> } </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-3">"@foxxmd/logging/factory"</span><span class="hl-1">;</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">errorFileDestination</span><span class="hl-1"> = </span><span class="hl-6">buildDestinationFile</span><span class="hl-1">(</span><span class="hl-3">'error'</span><span class="hl-1">, {</span><span class="hl-0">path:</span><span class="hl-1"> </span><span class="hl-3">'./myLogs/warn.log'</span><span class="hl-1">});</span><br/><br/><span class="hl-7">// also logs to console and file at 'info' level</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">logger</span><span class="hl-1"> = </span><span class="hl-6">loggerApp</span><span class="hl-1">({}, {</span><br/><span class="hl-1"> </span><span class="hl-0">destinations:</span><span class="hl-1"> [</span><span class="hl-0">errorFileDestination</span><span class="hl-1">]</span><br/><span class="hl-1">});</span>
163</code><button type="button">Copy</button></pre>
164
165<a id="md:log-raw-newline-delimited-json-logs-to-additional-file" class="tsd-anchor"></a><h4 class="tsd-anchor-link">Log raw, newline-delimited json logs to additional File<a href="#md:log-raw-newline-delimited-json-logs-to-additional-file" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h4><pre><code class="ts"><span class="hl-2">import</span><span class="hl-1"> {</span><span class="hl-0">loggerApp</span><span class="hl-1">} </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-3">'@foxxmd/logging'</span><span class="hl-1">;</span><br/><span class="hl-2">import</span><span class="hl-1"> { </span><span class="hl-0">buildDestinationFile</span><span class="hl-1"> } </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-3">"@foxxmd/logging/factory"</span><span class="hl-1">;</span><br/><span class="hl-2">import</span><span class="hl-1"> </span><span class="hl-0">fs</span><span class="hl-1"> </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-3">'node:fs'</span><span class="hl-1">;</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">rawFile</span><span class="hl-1"> = </span><span class="hl-0">fs</span><span class="hl-1">.</span><span class="hl-6">createWriteStream</span><span class="hl-1">(</span><span class="hl-3">'myRawFile.log'</span><span class="hl-1">);</span><br/><br/><span class="hl-7">// also logs to console and file at 'info' level</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">logger</span><span class="hl-1"> = </span><span class="hl-6">loggerApp</span><span class="hl-1">({}, {</span><br/><span class="hl-1"> </span><span class="hl-0">destinations:</span><span class="hl-1"> [</span><br/><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-0">level:</span><span class="hl-1"> </span><span class="hl-3">'debug'</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-0">stream:</span><span class="hl-1"> </span><span class="hl-0">rawFile</span><span class="hl-1"> </span><span class="hl-7">// logs are NOT prettified, only raw data from pino</span><br/><span class="hl-1"> }</span><br/><span class="hl-1"> ]</span><br/><span class="hl-1">});</span>
166</code><button type="button">Copy</button></pre>
167
168<a id="md:log-prettified-data-to-additional-stream" class="tsd-anchor"></a><h4 class="tsd-anchor-link">Log prettified data to additional stream<a href="#md:log-prettified-data-to-additional-stream" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h4><p>This could be used to trigger something when a log object with a specific property is found. Or to stream prettified log json to a client over websockets.</p>
169<p>To emit data as an object (<a href="https://foxxmd.github.io/logging/types/index.LogDataPretty.html" target="_blank" class="external"><code>LogDataPretty</code></a>) set <code>objectMode</code> and <code>object</code> to true.</p>
170<pre><code class="ts"><span class="hl-2">import</span><span class="hl-1"> {</span><span class="hl-0">loggerApp</span><span class="hl-1">} </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-3">'@foxxmd/logging'</span><span class="hl-1">;</span><br/><span class="hl-2">import</span><span class="hl-1"> { </span><span class="hl-0">buildDestinationJsonPrettyStream</span><span class="hl-1"> } </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-3">"@foxxmd/logging/factory"</span><span class="hl-1">;</span><br/><span class="hl-2">import</span><span class="hl-1"> { </span><span class="hl-0">PassThrough</span><span class="hl-1"> } </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-3">"node:stream"</span><span class="hl-1">;</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">prettyObjectStream</span><span class="hl-1"> = </span><span class="hl-4">new</span><span class="hl-1"> </span><span class="hl-6">Passthrough</span><span class="hl-1">({</span><span class="hl-0">objectMode:</span><span class="hl-1"> </span><span class="hl-4">true</span><span class="hl-1">}); </span><span class="hl-7">// objectMode MUST be true to get objects from the stream</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">prettyObjectDestination</span><span class="hl-1"> = </span><span class="hl-6">buildDestinationJsonPrettyStream</span><span class="hl-1">(</span><span class="hl-3">'debug'</span><span class="hl-1">, {</span><br/><span class="hl-1"> </span><span class="hl-0">destination:</span><span class="hl-1"> </span><span class="hl-0">prettyObjectStream</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-0">object:</span><span class="hl-1"> </span><span class="hl-4">true</span><span class="hl-1">, </span><span class="hl-7">// must be set to true to use with objectMode stream</span><br/><span class="hl-1"> </span><span class="hl-0">colorize:</span><span class="hl-1"> </span><span class="hl-4">true</span><br/><span class="hl-1">});</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">prettyStringStream</span><span class="hl-1"> = </span><span class="hl-4">new</span><span class="hl-1"> </span><span class="hl-6">Passthrough</span><span class="hl-1">(); </span><span class="hl-7">// will emit data as a json string</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">prettyStringDestination</span><span class="hl-1"> = </span><span class="hl-6">buildDestinationJsonPrettyStream</span><span class="hl-1">(</span><span class="hl-3">'debug'</span><span class="hl-1">, {</span><br/><span class="hl-1"> </span><span class="hl-0">destination:</span><span class="hl-1"> </span><span class="hl-0">prettyStringStream</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-0">object:</span><span class="hl-1"> </span><span class="hl-4">false</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-0">colorize:</span><span class="hl-1"> </span><span class="hl-4">true</span><br/><span class="hl-1">});</span><br/><br/><span class="hl-7">// also logs to console and file at 'info' level</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">logger</span><span class="hl-1"> = </span><span class="hl-6">loggerApp</span><span class="hl-1">({}, {</span><br/><span class="hl-1"> </span><span class="hl-0">destinations:</span><span class="hl-1"> [</span><br/><span class="hl-1"> </span><span class="hl-0">prettyObjectDestination</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-0">prettyStringDestination</span><br/><span class="hl-1"> ]</span><br/><span class="hl-1">});</span><br/><br/><span class="hl-0">prettyObjectStream</span><span class="hl-1">.</span><span class="hl-6">on</span><span class="hl-1">(</span><span class="hl-3">'data'</span><span class="hl-1">, (</span><span class="hl-0">log</span><span class="hl-1">) </span><span class="hl-4">=></span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-7">// do something with log object (LogDataPretty) </span><br/><span class="hl-1">});</span><br/><br/><span class="hl-0">prettyStringStream</span><span class="hl-1">.</span><span class="hl-6">on</span><span class="hl-1">(</span><span class="hl-3">'data'</span><span class="hl-1">, (</span><span class="hl-0">log</span><span class="hl-1">) </span><span class="hl-4">=></span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-7">// do something with log string</span><br/><span class="hl-1">});</span>
171</code><button type="button">Copy</button></pre>
172
173<a id="md:log-to-additional-pino-transports" class="tsd-anchor"></a><h4 class="tsd-anchor-link">Log to additional Pino Transports<a href="#md:log-to-additional-pino-transports" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h4><p>Log to a <a href="https://getpino.io/#/docs/transports" target="_blank" class="external">Pino Transport</a> like <a href="https://getpino.io/#/docs/transports?id=pino-elasticsearch" target="_blank" class="external">pino-elasticsearch</a>:</p>
174<pre><code class="ts"><span class="hl-2">import</span><span class="hl-1"> {</span><span class="hl-0">loggerApp</span><span class="hl-1">} </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-3">'@foxxmd/logging'</span><span class="hl-1">;</span><br/><span class="hl-2">import</span><span class="hl-1"> </span><span class="hl-0">pinoElastic</span><span class="hl-1"> </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-3">'pino-elasticsearch'</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">streamToElastic</span><span class="hl-1"> = </span><span class="hl-6">pinoElastic</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-0">index:</span><span class="hl-1"> </span><span class="hl-3">'an-index'</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-0">node:</span><span class="hl-1"> </span><span class="hl-3">'http://localhost:9200'</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-0">esVersion:</span><span class="hl-1"> </span><span class="hl-9">7</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-0">flushBytes:</span><span class="hl-1"> </span><span class="hl-9">1000</span><br/><span class="hl-1">});</span><br/><br/><span class="hl-7">// also logs to console and file at 'info' level</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">logger</span><span class="hl-1"> = </span><span class="hl-6">loggerApp</span><span class="hl-1">({}, {</span><br/><span class="hl-1"> </span><span class="hl-0">destinations:</span><span class="hl-1"> [</span><br/><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-0">level:</span><span class="hl-1"> </span><span class="hl-3">'debug'</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-0">stream:</span><span class="hl-1"> </span><span class="hl-0">streamToElastic</span><br/><span class="hl-1"> }</span><br/><span class="hl-1"> ]</span><br/><span class="hl-1">});</span>
175</code><button type="button">Copy</button></pre>
176
177</div></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-external" name="external"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>External</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="assets/icons.svg#icon-chevronDown"></use></svg>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#md:foxxmdlogging"><span>@foxxmd/logging</span></a><a href="#md:install"><span>Install</span></a><a href="#md:quick-start"><span>Quick <wbr/>Start</span></a><a href="#md:loggers"><span>Loggers</span></a><ul><li><ul><li><a href="#md:app-loggers"><span>App <wbr/>Loggers</span></a></li><li><a href="#md:helper-loggers"><span>Helper <wbr/>Loggers</span></a></li></ul></li><li><a href="#md:configuring"><span>Configuring</span></a></li><li><ul><li><ul><li><a href="#md:colorizing-docker-logs"><span>Colorizing <wbr/>Docker <wbr/>Logs</span></a></li></ul></li></ul></li><li><a href="#md:usage"><span>Usage</span></a></li><li><ul><li><a href="#md:child-loggers"><span>Child <wbr/>Loggers</span></a></li><li><ul><li><a href="#md:filtering-by-label"><span>Filtering <wbr/>By <wbr/>Label</span></a></li></ul></li><li><a href="#md:serializing-objects-and-errors"><span>Serializing <wbr/>Objects and <wbr/>Errors</span></a></li></ul></li></ul><a href="#md:building-a-logger"><span>Building <wbr/>A <wbr/>Logger</span></a><ul><li><ul><li><a href="#md:example"><span>Example</span></a></li><li><a href="#md:parsing-logoptions"><span>Parsing <wbr/>Log<wbr/>Options</span></a></li></ul></li></ul><a href="#md:examples"><span>Examples</span></a><ul><li><a href="#md:log-to-console-and-file"><span>Log to <wbr/>Console and <wbr/>File</span></a></li><li><a href="#md:log-at-specific-level-or-higher-for-console-and-file"><span>Log <wbr/>At <wbr/>Specific <wbr/>Level <wbr/>Or <wbr/>Higher for <wbr/>Console and <wbr/>File</span></a></li><li><a href="#md:log-at-debug-for-console-and-warn-for-file"><span>Log <wbr/>At debug for <wbr/>Console and warn for <wbr/>File</span></a></li><li><a href="#md:do-not-log-to-file"><span>Do not log to <wbr/>File</span></a></li><li><a href="#md:log-to-specific-file"><span>Log to <wbr/>Specific <wbr/>File</span></a></li><li><a href="#md:log-to-rolling-file-with-unix-timestamp"><span>Log to <wbr/>Rolling <wbr/>File with <wbr/>Unix <wbr/>Timestamp</span></a></li><li><a href="#md:log-to-rolling-file-with-no-timestamp"><span>Log to <wbr/>Rolling <wbr/>File with no timestamp</span></a></li><li><a href="#md:log-to-additional-file-for-error-only"><span>Log to additional <wbr/>File for 'error' only</span></a></li><li><a href="#md:log-raw-newline-delimited-json-logs-to-additional-file"><span>Log raw, newline-<wbr/>delimited json logs to additional <wbr/>File</span></a></li><li><a href="#md:log-prettified-data-to-additional-stream"><span>Log prettified data to additional stream</span></a></li><li><a href="#md:log-to-additional-pino-transports"><span>Log to additional <wbr/>Pino <wbr/>Transports</span></a></li></ul></div></details></div><div class="site-menu"><nav id="tsd-sidebar-links" class="tsd-navigation"><a href="http://foxxmd.github.io/logging" class="tsd-nav-link">Docs</a><a href="https://github.com/foxxmd/logging" class="tsd-nav-link">GitHub</a></nav><nav class="tsd-navigation"><a href="index.html" class="current"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-1"></use></svg><span>@foxxmd/logging Docs</span></a><ul class="tsd-small-nested-navigation" id="tsd-nav-container" data-base="."><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>