diff --git a/README.md b/README.md
index 5f61cfeb..fba81044 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@
[![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier)
[![GitHub stars](https://img.shields.io/github/stars/fullstack-build/tslog.svg?style=social&label=Star)](https://github.com/fullstack-build/tslog)
-> Powerful, fast and expressive logging for Node.js
+> Powerful, fast and expressive logging for Node.js
![tslog pretty output](https://raw.githubusercontent.com/fullstack-build/tslog/master/docs/assets/tslog_pretty_output.png "tslog pretty output")
@@ -39,14 +39,14 @@ const log: Logger = new Logger();
log.silly("I am a silly log.");
```
-### Install
+### Install
```bash
npm install tslog
```
**Enable TypeScript source map support:**
-This feature enables `tslog` to reference a correct line number in your TypeScript source code.
+This feature enables `tslog` to reference a correct line number in your TypeScript source code.
```json5
// tsconfig.json
@@ -79,12 +79,12 @@ log.fatal(new Error("I am a pretty Error with a stacktrace."));
* **Log level:** `silly`, `trace`, `debug`, `info`, `warn`, `error`, `fatal` (different colors)
* **Output to std:** Structured/_pretty_ output (easy parsable `tab` delimiters), `JSON` or suppressed
* **Attachable transports:** Send logs to an external log aggregation services, file system, database, or email/slack/sms/you name it...
-* **StdOut or StdErr depends on log level:** **_stdout_** for `silly`, `trace`, `debug`, `info` and **_stderr_** for `warn`, `error`, `fatal`
+* **StdOut or StdErr depends on log level:** **_stdout_** for `silly`, `trace`, `debug`, `info` and **_stderr_** for `warn`, `error`, `fatal`
* **Minimum log level per output:** `minLevel` level can be set individually per transport
* **Fully typed:** Written in TypeScript, fully typed, API checked with _api-extractor_, _TSDoc_ documented
* **Source maps lookup:** Shows exact position also in TypeScript code (compile-to-JS), one click to IDE position
-* **Stack trace:** Callsites through native _V8 stack trace API_, excludes internal entries
-* **Pretty Error:** Errors and stack traces printed in a structured way and fully accessible through _JSON_ (e.g. external Log services)
+* **Stack trace:** Callsites through native _V8 stack trace API_, excludes internal entries
+* **Pretty Error:** Errors and stack traces printed in a structured way and fully accessible through _JSON_ (e.g. external Log services)
* **Code frame:** `tslog` captures and displays the source code that lead to an error, making it easier to debug
* **Object/JSON highlighting:** Nicely prints out an object using native Node.js `utils.inspect` method
* **Instance Name:** Logs capture instance name (default host name) making it easy to distinguish logs coming from different instances (e.g. serverless)
@@ -177,7 +177,7 @@ interface ILogObject {
}
```
-There are three ways to access this object:
+There are three ways to access this object:
##### Returned by each log method
@@ -196,7 +196,7 @@ console.log(JSON.stringify(logWithTrace, null, 2));
```typescript
new Logger({ type: "json" });
```
-Resulting in the following output:
+Resulting in the following output:
![tslog log level json](https://raw.githubusercontent.com/fullstack-build/tslog/master/docs/assets/tslog_log_level_json.png)
@@ -206,8 +206,8 @@ Resulting in the following output:
#### Log level
-`tslog` is highly customizable, however, it follows _convention over configuration_ when it comes to **log levels**.
-Internally a log level is represented by a numeric ID.
+`tslog` is highly customizable, however, it follows _convention over configuration_ when it comes to **log levels**.
+Internally a log level is represented by a numeric ID.
Available log levels are:
`0: silly`, `1: trace`, `2: debug`, `3: info`, `4: warn`, `5: error`, `6: fatal`
@@ -215,9 +215,9 @@ Available log levels are:
Per default log level 0 - 3 are written to `stdout` and 4 - 6 are written to `stderr`.
Each log level is printed in a different color, that is customizable through the settings object.
-> **Hint:** Log level `trace` behaves a bit differently compared to all the other log levels.
-> While it is possible to activate a stack trace for every log level, it is already activated for `trace` by default.
-> That means every `trace` log will also automatically capture and print its entire stack trace.
+> **Hint:** Log level `trace` behaves a bit differently compared to all the other log levels.
+> While it is possible to activate a stack trace for every log level, it is already activated for `trace` by default.
+> That means every `trace` log will also automatically capture and print its entire stack trace.
```typescript
import { Logger } from "tslog";
@@ -232,17 +232,17 @@ log.error("I am an error log.");
log.fatal(new Error("I am a pretty Error with a stacktrace."));
```
-Structured (aka. _pretty_) log level output would look like this:
+Structured (aka. _pretty_) log level output would look like this:
![tslog log level structured](https://raw.githubusercontent.com/fullstack-build/tslog/master/docs/assets/tslog_log_level_pretty.png "tslog log level structured")
> **Hint:** Each logging method has a return type, which is a _JSON_ representation of the log message (`ILogObject`).
-> You can use this object to access its stack trace etc.
-> More details
+> You can use this object to access its stack trace etc.
+> More details
#### Child Logger
-Each `tslog` Logger instance can create child loggers and bequeath its settings to a child.
+Each `tslog` Logger instance can create child loggers and bequeath its settings to a child.
It is also possible to overwrite every setting when creating a child.
Child loggers are a powerful feature when building a modular application and due to its inheritance make it easy to configure the entire application.
@@ -258,44 +258,58 @@ const grandchildLogger: Logger = childLogger.getChildLogger({ name: "GrandChild
```
+#### Creating logger without source map support
+
+By default, `Logger` creates instance with stack trace's source mapping support. For some cases, it may not be needed. `LoggerWithoutCallSite` returns same interface as `Logger` does and only disabling call site wrapping for source map.
+
+```typescript
+import { Logger, LoggerWithoutCallSite } from 'tslog';
+
+const logger = new Logger(...);
+const loggerWithoutCallSite = new LoggerWithoutCallSite(...);
+
+```
+
+Since `tslog` supports [tree-shaking](https://webpack.js.org/guides/tree-shaking/) via esm import syntax, importing `LoggerWithoutCallSite` without `Logger` will reduce overall bundle size.
+
#### Settings
-
-As `tslog` follows _convention over configuration_, it already comes with reasonable default settings.
+
+As `tslog` follows _convention over configuration_, it already comes with reasonable default settings.
Therefor all settings are optional. Nevertheless, they can be flexibly adapted to your own needs.
All possible settings are defined in the `ISettingsParam` interface and modern IDEs will provide auto-completion accordingly.
-
+
**You can use `setSettings()` to adjust settings at runtime.**
-> **Hint:** When changing settings at runtime this alternation would also propagate to every child loggers, as long as it has not been overwritten down the hierarchy.
+> **Hint:** When changing settings at runtime this alternation would also propagate to every child loggers, as long as it has not been overwritten down the hierarchy.
-##### `type`
+##### `type`
```default: "pretty"```
-Possible values: `"json" | "pretty" | "hidden"`
+Possible values: `"json" | "pretty" | "hidden"`
You can either `pretty` print logs, print them as `json` or hide them all together with `hidden` (e.g. when using custom transports).
Having `json` as an output format is particularly useful, if you want to forward your logs directly from your `std` to another log service.
-Instead of parsing a _pretty_ output, most log services prefer a _JSON_ representation.
+Instead of parsing a _pretty_ output, most log services prefer a _JSON_ representation.
> **Hint:** Printing in `json` gives you direct access to all the available information, like _stack trace_ and _code frame_ and so on.
```typescript
new Logger({ type: "json" });
```
-_Output:_
+_Output:_
![tslog log level json](https://raw.githubusercontent.com/fullstack-build/tslog/master/docs/assets/tslog_log_level_json.png)
> **Hint:** Each _JSON_ log is printed in one line, making it easily parsable by external services.
##### `instanceName`
```default: os.hostname``` _(hidden by default)_
-You can provide each logger with the name of the instance, making it easy to distinguish logs from different machines.
-This approach works well in the serverless environment as well, allowing you to filter all logs coming from a certain instance.
+You can provide each logger with the name of the instance, making it easy to distinguish logs from different machines.
+This approach works well in the serverless environment as well, allowing you to filter all logs coming from a certain instance.
-Per default `instanceName` is pre-filled with the `hostname` of your environment, which can be overwritten.
-However, this value is hidden by default in order to keep the log clean and tidy.
-You can change this behavior by setting `displayInstanceName` to `true`.
+Per default `instanceName` is pre-filled with the `hostname` of your environment, which can be overwritten.
+However, this value is hidden by default in order to keep the log clean and tidy.
+You can change this behavior by setting `displayInstanceName` to `true`.
```typescript
@@ -304,15 +318,15 @@ const logger: Logger = new Logger({ displayInstanceName: true });
const logger: Logger = new Logger({ displayInstanceName: true, instanceName: "ABC" });
// Would print out ABC as the name of this instance
-
+
```
##### `name`
```default: undefined```
-Each logger has an optional name, that is hidden by default. You can change this behavior by setting `displayLoggerName` to `true`.
-This setting is particularly interesting when working in a `monorepo`,
-giving you the possibility to provide each module/package with its own logger and being able to distinguish logs coming from different parts of your application.
+Each logger has an optional name, that is hidden by default. You can change this behavior by setting `displayLoggerName` to `true`.
+This setting is particularly interesting when working in a `monorepo`,
+giving you the possibility to provide each module/package with its own logger and being able to distinguish logs coming from different parts of your application.
```typescript
new Logger({ name: "myLogger" });
@@ -331,24 +345,24 @@ new Logger({ setCallerAsLoggerName: true });
##### `minLevel`
```default: "silly"```
-Minimum log level to be captured by this logger.
+Minimum log level to be captured by this logger.
Possible values are: `silly`, `trace`, `debug`, `info`, `warn`, `error`, `fatal`
##### `requestId`
```default: undefined```
-**❗ Keep track of all subsequent calls and promises originated from a single request (e.g. HTTP).**
+**❗ Keep track of all subsequent calls and promises originated from a single request (e.g. HTTP).**
In a real world application a call to an API would lead to many logs produced across the entire application.
-When debugging it can get quite handy to be able to group all logs based by a unique identifier `requestId`.
+When debugging it can get quite handy to be able to group all logs based by a unique identifier `requestId`.
A `requestId` can either be a `string` or a function.
-A string is suitable when you create a child logger for each request, while a function is helpful, when you need to reuse the same logger and need to obtain a `requistId` dynamically.
+A string is suitable when you create a child logger for each request, while a function is helpful, when you need to reuse the same logger and need to obtain a `requistId` dynamically.
**With Node.js 13.10, we got a new feature called AsyncLocalStorage.**
It has also been backported to Node.js v12.17.0 and of course it works with Node.js >= 14.
However it is still marked as *experimental*.
-Here is a blog post by Andrey Pechkurov describing ``AsyncLocalStorage`` and performing a small performance comparison.
+Here is a blog post by Andrey Pechkurov describing ``AsyncLocalStorage`` and performing a small performance comparison.
> **Hint**: If you prefer to use a more proven (yet slower) approach, you may want to check out `cls-hooked`.
@@ -356,12 +370,12 @@ Even though `tslog` is generic enough and works with any of these solutions our
`tslog` also works with any API framework (like `Express`, `Koa`, `Hapi` and so on), but we are going to use `Koa` in this example.
Based on this example it should be rather easy to create an `Express` or another middleware.
-Some provides (e.g. `Heroku`) already set a `X-Request-ID` header, which we are going to use or fallback to a short ID generated by `nanoid`.
+Some provides (e.g. `Heroku`) already set a `X-Request-ID` header, which we are going to use or fallback to a short ID generated by `nanoid`.
**In this example every subsequent logger is a child logger of the main logger and thus inherits all of its settings making `requestId` available throughout the entire application without any further ado.**
_index.ts:_
-```typescript
+```typescript
import * as Koa from 'koa';
import { AsyncLocalStorage } from "async_hooks";
import { customAlphabet } from "nanoid";
@@ -402,8 +416,8 @@ childLogger.info("Log containing requestId"); // <-- will contain a requestId
##### `exposeStack`
```default: false```
-
-Usually, only _Errors_ and log level `trace` logs would capture the entire stack trace.
+
+Usually, only _Errors_ and log level `trace` logs would capture the entire stack trace.
By enabling this option **every** stack trace of every log message is going to be captured.
```typescript
@@ -412,22 +426,22 @@ new Logger({ exposeStack: true });
![tslog with a stack trace](https://raw.githubusercontent.com/fullstack-build/tslog/master/docs/assets/tslog_stacktrace.png)
-> **Hint:** When working in an IDE like _WebStorm_ or an editor like _VSCode_ you can click on the path leading you directly to the position in your source code.
+> **Hint:** When working in an IDE like _WebStorm_ or an editor like _VSCode_ you can click on the path leading you directly to the position in your source code.
##### `exposeErrorCodeFrame`
```default: true```
-A nice feature of `tslog` is to capture the _code frame_ around the error caught, showing the _exact_ location of the error.
+A nice feature of `tslog` is to capture the _code frame_ around the error caught, showing the _exact_ location of the error.
While it comes quite handy during development, it also means that the source file (*.js or *.ts) needs to be loaded.
-When running in production, you probably want as much performance as possible and since errors are analyzed at a later point in time,
-you may want to disable this feature.
+When running in production, you probably want as much performance as possible and since errors are analyzed at a later point in time,
+you may want to disable this feature.
In order to keep the output clean and tidy, code frame does not follow into `node_modules`.
```typescript
new Logger({ exposeErrorCodeFrame: false });
```
-> **Hint:** By default 5 lines before and after the line with the error will be displayed.
+> **Hint:** By default 5 lines before and after the line with the error will be displayed.
> You can adjust this setting with `exposeErrorCodeFrameLinesBeforeAndAfter`.
![tslog with a code frame](https://raw.githubusercontent.com/fullstack-build/tslog/master/docs/assets/tslog_code_frame.png)
@@ -436,7 +450,7 @@ new Logger({ exposeErrorCodeFrame: false });
##### `ignoreStackLevels`
```default: 3```
-Defines how many stack levels should be ignored.
+Defines how many stack levels should be ignored.
`tslog` adds additional 3 layers to the stack and that the reason why the default is set to `3`.
You can increase this number, if you want to add additional layers (e.g. a factory class or a facade).
@@ -444,8 +458,8 @@ You can increase this number, if you want to add additional layers (e.g. a fact
##### `suppressStdOutput`
```default: false```
-It is possible to connect multiple _transports_ (external loggers) to `tslog` (see below).
-In this case it might be useful to suppress all output.
+It is possible to connect multiple _transports_ (external loggers) to `tslog` (see below).
+In this case it might be useful to suppress all output.
```typescript
new Logger({ suppressStdOutput: true });
@@ -454,15 +468,15 @@ new Logger({ suppressStdOutput: true });
##### `overwriteConsole`
```default: false```
-`tslog` is designed to be used directly through its API.
-However, there might be use cases, where you want to make sure to capture all logs,
-even though they might occur in a library or somebody else's code.
-Or maybe you prefer or used to work with `console`, like `console.log`, `console.warn` and so on.
+`tslog` is designed to be used directly through its API.
+However, there might be use cases, where you want to make sure to capture all logs,
+even though they might occur in a library or somebody else's code.
+Or maybe you prefer or used to work with `console`, like `console.log`, `console.warn` and so on.
In this case, you can advise `tslog` to overwrite the default behavior of `console`.
-> **Hint:** It is only possible to overwrite `console` once, so the last attempt wins.
-> If you wish to do so, I would recommend to have a designated logger for this purpose.
+> **Hint:** It is only possible to overwrite `console` once, so the last attempt wins.
+> If you wish to do so, I would recommend to have a designated logger for this purpose.
```typescript
new Logger({ name: "console", overwriteConsole: true });
@@ -481,36 +495,36 @@ _There is no `console.fatal`._
##### `colorizePrettyLogs`
```default: true```
-By default `pretty` output is colorized with ANSI escape codes. If you prefer a plain output, you can disable the colorization with this setting.
+By default `pretty` output is colorized with ANSI escape codes. If you prefer a plain output, you can disable the colorization with this setting.
##### `logLevelsColors`
This setting allows you to overwrite the default log level colors of `tslog`.
-Possible styles are:
+Possible styles are:
* Foreground colors
* Background colors
* Modifiers
-
+
##### `prettyInspectHighlightStyles`
This setting allows you to overwrite the default colors of `tslog` used for the native Node.js `utils.inspect` interpolation.
More Details: Customizing util.inspect colors
-##### `dateTimePattern`
+##### `dateTimePattern`
```default: "year-month-day hour:minute:second.millisecond"```
-Change the way `tslog` prints out the date.
-Based on Intl.DateTimeFormat.formatToParts with additional milliseconds, you can use type as a placeholder.
+Change the way `tslog` prints out the date.
+Based on Intl.DateTimeFormat.formatToParts with additional milliseconds, you can use type as a placeholder.
Available placeholders are: `day`, `dayPeriod`, `era`, `hour`, `literal`, `minute`, `month`, `second`, `millisecond`, `timeZoneName`, `weekday` and `year`.
-##### `dateTimeTimezone`
+##### `dateTimeTimezone`
```default: "utc" ```
Define in which timezone the date should be printed in.
-Possible values are `utc` and IANA (Internet Assigned Numbers Authority) based timezones, e.g. `Europe/Berlin`, `Europe/Moscow` and so on.
+Possible values are `utc` and IANA (Internet Assigned Numbers Authority) based timezones, e.g. `Europe/Berlin`, `Europe/Moscow` and so on.
-> **Hint:** If you want to use your local time zone, you can set:
+> **Hint:** If you want to use your local time zone, you can set:
> `dateTimeTimezone: Intl.DateTimeFormat().resolvedOptions().timeZone`
##### `prefix`
@@ -519,8 +533,8 @@ Possible values are `utc` and **Hint:** It will also mask keys if it encounters a matching pattern.
+> **Hint:** It will also mask keys if it encounters a matching pattern.
**`maskValuesOfKeys` is case sensitive!**
@@ -625,7 +639,7 @@ let secretiveObject = {
verySecretiveLogger.info(secretiveObject);
// Output:
-// INFO [SecretiveLogger]
+// INFO [SecretiveLogger]
// {
// Authorization: '[***]',
// regularString: 'I am just a regular string.',
@@ -640,60 +654,60 @@ verySecretiveLogger.info(secretiveObject);
> **Hint:** useful for API keys and other secrets (e.g. from ENVs).
-##### `maskPlaceholder`
+##### `maskPlaceholder`
```default: "[***]" ```
String to use for masking of secrets (s. `maskAnyRegEx` & `maskValuesOfKeys`)
-##### `printLogMessageInNewLine`
+##### `printLogMessageInNewLine`
```default: false ```
-By default `tslog` uses `tab` delimiters for separation of the meta information (date, log level, etc.) and the log parameters.
-Since the meta information can become quite long, you may want to prefer to print the log attributes in a new line.
+By default `tslog` uses `tab` delimiters for separation of the meta information (date, log level, etc.) and the log parameters.
+Since the meta information can become quite long, you may want to prefer to print the log attributes in a new line.
-##### `displayDateTime`
+##### `displayDateTime`
```default: true ```
-Defines whether the date time should be displayed.
+Defines whether the date time should be displayed.
-##### `displayLogLevel`
+##### `displayLogLevel`
```default: true ```
-Defines whether the log level should be displayed.
+Defines whether the log level should be displayed.
-##### `displayInstanceName`
+##### `displayInstanceName`
```default: false ```
-Defines whether the instance name (e.g. host name) should be displayed.
+Defines whether the instance name (e.g. host name) should be displayed.
-##### `displayLoggerName`
+##### `displayLoggerName`
```default: true ```
-Defines whether the optional logger name should be displayed.
+Defines whether the optional logger name should be displayed.
-##### `displayRequestId`
+##### `displayRequestId`
```default: true ```
-Defines whether the `requestId` should be displayed, if set and available (s. `requestId`).
+Defines whether the `requestId` should be displayed, if set and available (s. `requestId`).
-##### `displayFunctionName`
+##### `displayFunctionName`
```default: true ```
-Defines whether the class and method or function name should be displayed.
+Defines whether the class and method or function name should be displayed.
-##### `displayTypes`
+##### `displayTypes`
```default: false ```
Defines whether type information (`typeof`) of every attribute passed to `tslog` should be displayed.
-##### `displayFilePath`
+##### `displayFilePath`
```default: hideNodeModulesOnly ```
-Defines whether file path and line should be displayed or not.
-There are 3 possible settgins:
+Defines whether file path and line should be displayed or not.
+There are 3 possible settgins:
* `hidden`
* `displayAll`
* `hideNodeModulesOnly` (default): This setting will hide all file paths containing `node_modules`.
@@ -701,28 +715,28 @@ There are 3 possible settgins:
##### `stdOut` and `stdErr`
-This both settings allow you to replace the default `stdOut` and `stdErr` _WriteStreams_.
-However, this would lead to a colorized output. We use this setting mostly for testing purposes.
-If you want to redirect the output or directly access any logged object, we advise you to **attach a transport** (see below).
+This both settings allow you to replace the default `stdOut` and `stdErr` _WriteStreams_.
+However, this would lead to a colorized output. We use this setting mostly for testing purposes.
+If you want to redirect the output or directly access any logged object, we advise you to **attach a transport** (see below).
#### Transports
-`tslog` focuses on the one thing it does well: capturing logs.
-Therefore, there is no build-in _file system_ logging, _log rotation_, or similar.
-Per default all logs go to `stdOut` and `stdErr` respectively.
+`tslog` focuses on the one thing it does well: capturing logs.
+Therefore, there is no build-in _file system_ logging, _log rotation_, or similar.
+Per default all logs go to `stdOut` and `stdErr` respectively.
However, you can easily attach as many _transports_ as you wish, enabling you to do fancy stuff
-like sending a message to _Slack_ or _Telegram_ in case of an urgent error.
+like sending a message to _Slack_ or _Telegram_ in case of an urgent error.
-When attaching a transport, you _must_ implement every log level.
+When attaching a transport, you _must_ implement every log level.
All of them could be potentially handled by the same function, though.
Each _transport_ can have its own `minLevel`.
-**Attached transports are also inherited to child loggers.**
+**Attached transports are also inherited to child loggers.**
##### Simple transport example
-Here is a very simple implementation used in our _jest_ tests:
+Here is a very simple implementation used in our _jest_ tests:
```typescript
import { ILogObject, Logger } from "tslog";
@@ -750,7 +764,7 @@ logger.attachTransport(
##### Storing logs in a file
-Here is an example how to store all logs in a file.
+Here is an example how to store all logs in a file.
```typescript
import { ILogObject, Logger } from "tslog";
@@ -788,10 +802,10 @@ logger.warn("I am a warn log with a json object:", { foo: "bar" });
#### Helper
##### prettyError
-Sometimes you just want to _pretty print_ an error without having to log it, or maybe just catch its call sites, or it's stack frame? If so, this helper is for you.
-`prettyError` exposes all the awesomeness of `tslog` without the actual logging. A possible use case could be in a CLI, or other internal helper tools.
+Sometimes you just want to _pretty print_ an error without having to log it, or maybe just catch its call sites, or it's stack frame? If so, this helper is for you.
+`prettyError` exposes all the awesomeness of `tslog` without the actual logging. A possible use case could be in a CLI, or other internal helper tools.
-Example:
+Example:
```typescript
const logger: Logger = new Logger();
const err: Error = new Error("Test Error");
@@ -809,7 +823,7 @@ logger.prettyError(err);
* `std` - Which std should the output be printed to? _(default: stdErr)_
##### printPrettyLog
-If you just want to _pretty print_ an error on a custom output (for adding a new transport for example),
+If you just want to _pretty print_ an error on a custom output (for adding a new transport for example),
you can just call `logger.printPrettyLog(myStd, myLogObject)` where myStd is an instance of `IStd` (e.g. `process.stdout`, `process.stderr` or even a custom one, see example below):
```typescript