Skip to content

Commit bb0f230

Browse files
authored
Merge pull request #172 from fullstack-build/development
Development
2 parents ee17c7f + d866d8f commit bb0f230

File tree

5 files changed

+132
-98
lines changed

5 files changed

+132
-98
lines changed

README.md

Lines changed: 50 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212

1313
> Powerful, fast and expressive logging for TypeScript and JavaScript
14-
14+
1515
![tslog pretty output](https://raw.githubusercontent.com/fullstack-build/tslog/master/docs/assets/tslog.png "tslog pretty output in browser and Node.js")
1616

1717

@@ -49,13 +49,13 @@ Donations help me allocate more time for my open source work.
4949

5050
## Install
5151

52-
> **`tslog` is a native ES module.**
52+
> **`tslog` is a native ES module.**
5353
5454
```bash
5555
npm install tslog
5656
```
5757

58-
In order to run a native ES module in Node.js, you have to do two things:
58+
In order to run a native ES module in Node.js, you have to do two things:
5959

6060
1) Set `"type": "module"` in `package.json`.
6161
2) For now, start with `--experimental-specifier-resolution=node`
@@ -180,21 +180,21 @@ logger.fatal(new Error("I am a pretty Error with a stacktrace."));
180180

181181
## API documentation
182182

183-
> **`tslog >= v4` is a major rewrite and introduces breaking changes.** <br>
184-
> Please, follow this documentation when migrating.
183+
> **`tslog >= v4` is a major rewrite and introduces breaking changes.** <br>
184+
> Please, follow this documentation when migrating.
185185
186186
### <a name="life_cycle"></a>Lifecycle of a log message
187187

188-
Every incoming log message runs through a number of steps before being displayed or handed over to a "transport". Every step can be overwritten and adjusted.
188+
Every incoming log message runs through a number of steps before being displayed or handed over to a "transport". Every step can be overwritten and adjusted.
189189

190190
![tslog pretty output](https://raw.githubusercontent.com/fullstack-build/tslog/master/docs/assets/tslog_lifesycle.png "tslog: life cycle of a log message")
191191

192192
- **log message** Log message comes in through the `BaseLogger.log()` method
193193
- **mask** If masking is configured, log message gets recursively masked
194-
- **toLogObj** Log message gets transformed into a log object: A default typed log object can be passed to constructor as a second parameter and will be cloned and enriched with the incoming log parameters. Error properties will be handled accordingly. If there is only one log property, and it's an object, both objects (cloned default `logObj` as well as the log property object) will be merged. If there are more than one, they will be put into properties called "0", "1", ... and so on. Alternatively, log message properties can be put into a property with a name configured with the `argumentsArrayName` setting.
194+
- **toLogObj** Log message gets transformed into a log object: A default typed log object can be passed to constructor as a second parameter and will be cloned and enriched with the incoming log parameters. Error properties will be handled accordingly. If there is only one log property, and it's an object, both objects (cloned default `logObj` as well as the log property object) will be merged. If there are more than one, they will be put into properties called "0", "1", ... and so on. Alternatively, log message properties can be put into a property with a name configured with the `argumentsArrayName` setting.
195195
- **addMetaToLogObj** Additional meta information, like the source code position of the log will be gathered and added to the `_meta` property or any other one configured with the setting `metaProperty`.
196-
- **format** In case of "pretty" configuration, a log object will be formatted based on the templates configured in settings. Meta will be formatted by the method `_prettyFormatLogObjMeta` and the actual log payload will be formatted by `prettyFormatLogObj`. Both steps can be overwritten with the settings `formatMeta` and `formatMeta`.
197-
- **transport** Last step is to "transport" a log message to every attached transport from the setting `attachedTransports`. Last step is the actual transport, either JSON (`transportJSON`), formatted (`transportFormatted`) or omitted, if its set to "hidden". Both default transports can also be overwritten by the corresponding setting.
196+
- **format** In case of "pretty" configuration, a log object will be formatted based on the templates configured in settings. Meta will be formatted by the method `_prettyFormatLogObjMeta` and the actual log payload will be formatted by `prettyFormatLogObj`. Both steps can be overwritten with the settings `formatMeta` and `formatMeta`.
197+
- **transport** Last step is to "transport" a log message to every attached transport from the setting `attachedTransports`. Last step is the actual transport, either JSON (`transportJSON`), formatted (`transportFormatted`) or omitted, if its set to "hidden". Both default transports can also be overwritten by the corresponding setting.
198198

199199
### Default log level
200200

@@ -245,16 +245,16 @@ export class CustomLogger<LogObj> extends BaseLogger<LogObj> {
245245
```
246246

247247
### Settings
248-
`tslog` is highly customizable and pretty much every aspect can be either configured or overwritten.
248+
`tslog` is highly customizable and pretty much every aspect can be either configured or overwritten.
249249
A `settings` object is the first parameter passed to the `tslog` constructor:
250250

251-
```typescript
251+
```typescript
252252
const logger = new Logger<ILogObj>({ /* SETTINGS */ }, defaultLogObject);
253253
```
254254

255255
#### Type: pretty, json, hidden
256256

257-
- `pretty` **Default setting** prints out a formatted structured "pretty" log entry.
257+
- `pretty` **Default setting** prints out a formatted structured "pretty" log entry.
258258
- `json` prints out a `JSON` formatted log entry.
259259
- `hidden` suppresses any output whatsoever and can be used with attached loggers for example.
260260

@@ -275,16 +275,16 @@ const hiddenLogger = new Logger({type: "hidden"});
275275

276276
#### name
277277

278-
Each logger has an optional name.
279-
You can find the name of the logger responsible for a log inside the `Meta`-object or printed in `pretty` mode.
280-
Names get also inherited to sub loggers and can be found inside the `Meta`-object `parentNames` as well as printed out with a separator (e.g. `:`) in `pretty` mode.
278+
Each logger has an optional name.
279+
You can find the name of the logger responsible for a log inside the `Meta`-object or printed in `pretty` mode.
280+
Names get also inherited to sub loggers and can be found inside the `Meta`-object `parentNames` as well as printed out with a separator (e.g. `:`) in `pretty` mode.
281281

282282
Simple name example:
283283
```typescript
284284
new Logger({ name: "myLogger" });
285285
```
286286

287-
Sub-loggers with an inherited name:
287+
Sub-loggers with an inherited name:
288288
```typescript
289289
const mainLogger = new Logger({ type: "pretty", name: "MainLogger" });
290290
mainLogger.silly("foo bar");
@@ -296,11 +296,11 @@ const secondSubLogger = firstSubLogger.getSubLogger({ name: "SecondSubLogger" })
296296
secondSubLogger.silly("foo bar 2");
297297
```
298298

299-
Output:
299+
Output:
300300
```bash
301-
2022-11-17 10:45:47.705 SILLY [/examples/nodejs/index2.ts:51 MainLogger] foo bar
302-
2022-11-17 10:45:47.706 SILLY [/examples/nodejs/index2.ts:54 MainLogger:FirstSubLogger] foo bar 1
303-
2022-11-17 10:45:47.706 SILLY [/examples/nodejs/index2.ts:57 MainLogger:FirstSubLogger:SecondSubLogger] foo bar 2
301+
2022-11-17 10:45:47.705 SILLY [/examples/nodejs/index2.ts:51] MainLogger foo bar
302+
2022-11-17 10:45:47.706 SILLY [/examples/nodejs/index2.ts:54] MainLogger:FirstSubLogger foo bar 1
303+
2022-11-17 10:45:47.706 SILLY [/examples/nodejs/index2.ts:57] MainLogger:FirstSubLogger:SecondSubLogger foo bar 2
304304
```
305305

306306
#### minLevel
@@ -318,7 +318,7 @@ suppressSilly.trace("Will be visible");
318318

319319
#### argumentsArrayName
320320

321-
`tslog` < 4 wrote all parameters into an arguments array. In `tslog` >= 4 the main object becomes home for all log parameters, and they get merged with the default `logObj`.
321+
`tslog` < 4 wrote all parameters into an arguments array. In `tslog` >= 4 the main object becomes home for all log parameters, and they get merged with the default `logObj`.
322322
If you still want to put them into a separated parameter, you can do so by defining the `argumentsArrayName`.
323323

324324
```typescript
@@ -344,7 +344,7 @@ Enables you to overwrite the looks of a formatted _"pretty"_ log message by prov
344344
Following settings are available for styling:
345345

346346
- **Templates:**
347-
- `prettyLogTemplate`: template string for log messages. Possible placeholders:
347+
- `prettyLogTemplate`: template string for log messages. Possible placeholders:
348348
- `{{yyyy}}`: year
349349
- `{{mm}}`: month
350350
- `{{dd}}`: day
@@ -353,31 +353,33 @@ Following settings are available for styling:
353353
- `{{ss}}`: seconds
354354
- `{{ms}}`: milliseconds
355355
- `{{dateIsoStr}}`: Shortcut for `{{yyyy}}.{{mm}}.{{dd}} {{hh}}:{{MM}}:{{ss}}:{{ms}}`
356+
- `{{rawIsoStr}}`: Renders the date and time in ISO format (e.g.: YYYY-MM-DDTHH:mm:ss.SSSZ)
356357
- `{{logLevelName}}`: name of the log level
357358
- `{{name}}`: optional name of the current logger and his parents (e.g. "ParentLogger:ThisLogger")
358359
- `{{fullFilePath}}`: a full path starting from `/` root
359360
- `{{filePathWithLine}}`: a full path below the project path with line number
360361
- `prettyErrorTemplate`: template string for error message. Possible placeholders:
361362
- `{{errorName}}`: name of the error
362363
- `{{errorMessage}}`: error message
363-
- `{{errorStack}}`: Placeholder for all stack lines defined by `prettyErrorStackTemplate`
364+
- `{{errorStack}}`: Placeholder for all stack lines defined by `prettyErrorStackTemplate`
364365
- `prettyErrorStackTemplate`: template string for error stack trace lines. Possible placeholders:
365366
- `{{fileName}}`: name of the file
366367
- `{{filePathWithLine}}`: a full path below the project path with a line number
367368
- `{{method}}`: _optional_ name of the invoking method
368369
- `prettyErrorParentNamesSeparator`: separator to be used when joining names ot the parent logger, and the current one (default: `:`)
370+
- `prettyErrorLoggerNameDelimiter`: if a logger name is set this delimiter will be added afterwards
369371
- `prettyInspectOptions`: <a href="https://nodejs.org/api/util.html#utilinspectobject-options" target="_blank">Available options</a>
370-
372+
371373
- **Styling:**
372374
- `stylePrettyLogs`: defines whether logs should be styled and colorized
373375
- `prettyLogStyles`: provides colors and styles for different placeholders and can also be dependent on the value (e.g. log level)
374376
- Level 1: template placeholder (defines a style for a certain template placeholder, s. above, without brackets).
375-
- Level 2: Either a string with one style (e.g. `white`), or an array of styles (e.g. `["bold", "white"]`), or a nested object with key being a value.
377+
- Level 2: Either a string with one style (e.g. `white`), or an array of styles (e.g. `["bold", "white"]`), or a nested object with key being a value.
376378
- Level 3: Optional nested style based on placeholder values. Key is the value of the template placeholder and value is either a string of a style, or an array of styles (s. above), e.g. `{ SILLY: ["bold", "white"] }` which means: value "SILLY" should get a style of "bold" and "white". `*` means any value other than the defined.
377379
- `prettyInspectOptions`: When a (potentially nested) object is printed out in Node.js, we use `util.formatWithOptions` under the hood. With `prettyInspectOptions` you can define the output. [Possible values](https://nodejs.org/api/util.html#utilinspectobject-showhidden-depth-colors)
378380

379381
#### Log meta information
380-
`tslog` collects meta information for every log, like runtime, code position etc. The meta information collected depends on the runtime (browser or Node.js) and is accessible through the `LogObj`.
382+
`tslog` collects meta information for every log, like runtime, code position etc. The meta information collected depends on the runtime (browser or Node.js) and is accessible through the `LogObj`.
381383
You can define the property containing this meta information with `metaProperty`, which is "_meta" by default.
382384

383385
#### Pretty templates and styles (color settings)
@@ -389,6 +391,7 @@ const logger = new Logger({
389391
prettyErrorTemplate: "\n{{errorName}} {{errorMessage}}\nerror stack:\n{{errorStack}}",
390392
prettyErrorStackTemplate: " • {{fileName}}\t{{method}}\n\t{{filePathWithLine}}",
391393
prettyErrorParentNamesSeparator: ":",
394+
prettyErrorLoggerNameDelimiter: "\t",
392395
stylePrettyLogs: true,
393396
prettyLogStyles: {
394397
logLevelName: {
@@ -403,7 +406,7 @@ const logger = new Logger({
403406
},
404407
dateIsoStr: "white",
405408
filePathWithLine: "white",
406-
name: "white",
409+
name: ["white", "bold"],
407410
errorName: ["bold", "bgRedBright", "whiteBright"],
408411
fileName: ["yellow"],
409412
},
@@ -467,7 +470,7 @@ like sending messages to _Slack_ or _Telegram_ in case of an urgent error or for
467470

468471
##### Simple transport example
469472

470-
Here is a very simple implementation used in our _jest_ tests.
473+
Here is a very simple implementation used in our _jest_ tests.
471474
This example will suppress logs from being sent to `console` (`type: "hidden"`) and will instead collect them in an `array`.
472475

473476
```typescript
@@ -502,10 +505,10 @@ logger.warn("I am a warn log with a json object:", { foo: "bar" });
502505

503506
##### Storing logs in a file system with rotating files
504507

505-
If you want to limit the file size of the stored logs, a good practice is to use file rotation, where old logs will be deleted automatically.
508+
If you want to limit the file size of the stored logs, a good practice is to use file rotation, where old logs will be deleted automatically.
506509
There is a great library called `rotating-file-stream` solving this problem for us and even adding features like compression, file size limit etc.
507510

508-
1. First you need to install this library:
511+
1. First you need to install this library:
509512
```bash
510513
npm i rotating-file-stream
511514
```
@@ -533,7 +536,7 @@ logger.warn("I am a warn log with a json object:", { foo: "bar" });
533536

534537
```
535538

536-
#### Overwriting default behavior
539+
#### Overwriting default behavior
537540

538541
One of the key advantages of `tslog` >= 4 is that you can overwrite pretty much every aspect of the log processing described in <a href="#life_cycle">"Lifecycle of a log message"</a>.
539542

@@ -567,7 +570,7 @@ For `pretty` logs:
567570
// format LogObj attributes to a string and return it
568571
},
569572
transportFormatted: (logMetaMarkup: string, logArgs: unknown[], logErrors: string[], settings: unknown) => {
570-
// overwrite the default transport for formatted (e.g. pretty) log levels. e.g. replace console with StdOut, write to file etc.
573+
// overwrite the default transport for formatted (e.g. pretty) log levels. e.g. replace console with StdOut, write to file etc.
571574
},
572575
},
573576
});
@@ -590,7 +593,7 @@ As described in <a href="#life_cycle">"Lifecycle of a log message"</a>, every lo
590593
A default logObj can be passed to the `tslog` constructor and will be cloned and merged into the log message. This makes `tslog` >= 4 highly configurable and easy to integrate into any 3rd party service.
591594
The entire `logObj` will be printed out in `JSON` mode and also returned by every log method.
592595

593-
> **Tip:** All properties of the default `LogObj` containing function calls will be executed for every log message making use cases possible like `requestId` (s. below).
596+
> **Tip:** All properties of the default `LogObj` containing function calls will be executed for every log message making use cases possible like `requestId` (s. below).
594597
595598
```typescript
596599
interface ILogObj {
@@ -602,7 +605,7 @@ const defaultLogObject: ILogObj = {
602605
};
603606

604607
const logger = new Logger<ILogObj>({ type: "json" }, defaultLogObject);
605-
const logMsg = logger.info("Test");
608+
const logMsg = logger.info("Test");
606609

607610
// logMsg: {
608611
// '0': 'Test',
@@ -648,24 +651,24 @@ Some providers (e.g. `Heroku`) already set a `X-Request-ID` header, which we are
648651
import Koa from "koa";
649652
import { customAlphabet } from "nanoid";
650653
import { Logger } from "tslog";
651-
654+
652655
interface ILogObj {
653656
requestId?: string | (() => string | undefined);
654657
}
655-
658+
656659
const asyncLocalStorage: AsyncLocalStorage<{ requestId: string }> = new AsyncLocalStorage();
657-
660+
658661
const defaultLogObject: ILogObj = {
659662
requestId: () => asyncLocalStorage.getStore()?.requestId,
660663
};
661-
664+
662665
const logger = new Logger<ILogObj>({ type: "json" }, defaultLogObject);
663666
export { logger };
664-
667+
665668
logger.info("Test log without requestId");
666-
669+
667670
const koaApp = new Koa();
668-
671+
669672
/** START AsyncLocalStorage requestId middleware **/
670673
koaApp.use(async (ctx: Koa.Context, next: Koa.Next) => {
671674
// use x-request-id or fallback to a nanoid
@@ -676,21 +679,21 @@ Some providers (e.g. `Heroku`) already set a `X-Request-ID` header, which we are
676679
});
677680
});
678681
/** END AsyncLocalStorage requestId middleware **/
679-
682+
680683
// example middleware
681684
koaApp.use(async (ctx: Koa.Context, next) => {
682-
685+
683686
// log request
684687
logger.silly({ originalUrl: ctx.originalUrl, status: ctx.response.status, message: ctx.response.message });
685-
688+
686689
// also works with a sub logger
687690
const subLogger = logger.getSubLogger();
688691
subLogger.info("Log containing requestId"); // <-- will contain a requestId
689-
692+
690693
return await next();
691694
});
692-
695+
693696
koaApp.listen(3000);
694-
697+
695698
logger.info("Server running on port 3000");
696699
```

0 commit comments

Comments
 (0)