Skip to content

Commit

Permalink
add global MessageDecoration
Browse files Browse the repository at this point in the history
  • Loading branch information
Reginald committed Aug 22, 2021
1 parent 9f97e09 commit 9a53e81
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 15 deletions.
29 changes: 25 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,15 @@ B.decorate(logger, logLeve, msg);
D.decorate(logger, logLeve, msg);
```

Each _derived_ logger manges its own `MessageDecoration` list. That is, adding a new decoration to the logger returned from `logger.tag()` will NOT affect the origin logger.
When a new logger derived from the origin logger, all the decorations of the origin logger will be copied to the derived one. The decorations of different derived loggers are managed separately.
In the other word, changing the decorations of one logger (even the main logger) will NOT affect the other existed logger, and vice versa.
##### Private MessageDecoration

Each _derived_ logger manages its own `MessageDecoration` list. That is, adding a new decoration to the logger returned from `logger.tag()` will NOT affect the origin logger.
When a new logger derived from the origin logger, all the private decorations of the origin logger will be copied to the derived one. The decorations of different derived loggers are managed separately.
In the other word, changing the private decorations of one logger (even the main logger) will NOT affect the other existed logger, and vice versa.
By default, a `MessageDecoration` for decorating the message with the `tag` and `tagSeparator` will be added as the first decoration with priority 0. We strongly recommend that DON'T call `logger.clearMessageDecorations()` at the main (origin) logger.
Instead, always build a derived logger (by calling `logger.tag('', '')`, for example) and then do whatever you like.

Several methods in `logger` are related to the management of the `MessageDecoration`:
Several methods in `logger` are related to the management of the private `MessageDecoration`s:

`logger.addMessageDecoration(messageDecoration: MessageDecoration): Logger`
Add decoration to logger.
Expand All @@ -90,6 +92,22 @@ Get a shallow copy of the decoration list of the logger. Remember that modify th
`logger.clearMessageDecorations(): Logger`
Clear the decorations of the logger.

##### Global MessageDecoration

All _derived_ loggers share a _global_ `MessageDecoration` list. Changing any global decoration on any `logger` will affect all the other `logger`s' behaviour.
When logging messages, private decorations and global decorations will be merged and ordered by their priorities. When a private decoration and a global decoration share the same priority number, the private one has the higher priority.

Several methods in `logger` are related to the management of the global `MessageDecoration`s:

`logger.addGlobalMessageDecoration(messageDecoration: MessageDecoration): Logger`
Add global decoration to all loggers.

`logger.getGlobalMessageDecorations(): MessageDecoration[]`
Get a shallow copy of the decoration list of the logger. Remember that modify the returned array will NOT affect the global decoration list.

`logger.clearGlobalMessageDecorations(): Logger`
Clear the global decorations of the logger.

##### MessageDecoration available outbox
Some `MessageDecoration`s are predefined and available outbox:

Expand Down Expand Up @@ -129,6 +147,9 @@ Here's the methods which will derive a new logger from the current logger when b

### Change logs

##### 0.3.1
Introduce _global MessageDecoration_ to `logger`, which will be applied to all derived `logger`s.

##### 0.3.0
`Logger` can contain more than one `MessageDecoration`, and all the decorations will be applied according to their priorities.
The tag and tag separator of the logger is handled by a `MessageDecoration` added to the logger at the very first beginning now.
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "node-common-logger",
"version": "0.3.0",
"version": "0.3.1",
"description": "A node library provides flexible logging ways and simple facade. User could use whatever implementations they like with the uniform api.",
"main": "./dist/index.js",
"types": "./typings/index.d.ts",
Expand Down
44 changes: 36 additions & 8 deletions src/Logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export default class Logger implements LogStrategy {

private strategy: LogStrategy;
private readonly messageDecorations: MessageDecoration[];
private readonly globalMessageDecorations: MessageDecoration[];

private currentTag?: string;
private tagSeparator?: string;
Expand All @@ -26,6 +27,7 @@ export default class Logger implements LogStrategy {
return logger.applyArgument(msg);
},
}];
this.globalMessageDecorations = [];
msgDecorations.forEach(decoration => this.addMessageDecoration(decoration));
}

Expand All @@ -44,13 +46,7 @@ export default class Logger implements LogStrategy {
}

addMessageDecoration(messageDecoration: MessageDecoration): Logger {
for (let [i, decoration] of this.messageDecorations.entries()) {
if ((messageDecoration.priority || 0) < (decoration.priority || 0)) {
this.messageDecorations.splice(i, 0, messageDecoration);
return this;
}
}
this.messageDecorations.push(messageDecoration);
Logger.insertMessageDecoration(this.messageDecorations, messageDecoration);
return this;
}

Expand All @@ -63,6 +59,20 @@ export default class Logger implements LogStrategy {
return this;
}

addGlobalMessageDecoration(messageDecoration: MessageDecoration): Logger {
Logger.insertMessageDecoration(this.globalMessageDecorations, messageDecoration);
return this;
}

getGlobalMessageDecorations(): MessageDecoration[] {
return [...this.globalMessageDecorations];
}

clearGlobalMessageDecorations(): Logger {
this.globalMessageDecorations.length = 0;
return this;
}

/**
* Fetch a specific named category logger. The result may be fetched from the cache unless <code>useCache</code> is
* set to <code>false</code>. Since the category is relative to the basic LogStrategy, the caches would be rebuilt if
Expand Down Expand Up @@ -208,6 +218,24 @@ export default class Logger implements LogStrategy {
}

private decorateMsg(logLevel: LogLevel, msg: string): string {
return this.messageDecorations.reduce((previousMsg, decoration) => decoration.decorate(this, logLevel, previousMsg), msg);
return this.mergeLocalAndGlobalDecorations().reduce((previousMsg, decoration) => decoration.decorate(this, logLevel, previousMsg), msg);
}

private mergeLocalAndGlobalDecorations(): MessageDecoration[] {
const messageDecorations = this.getMessageDecorations();
for (let globalMessageDecoration of this.globalMessageDecorations) {
Logger.insertMessageDecoration(messageDecorations, globalMessageDecoration);
}
return messageDecorations;
}

private static insertMessageDecoration(list: MessageDecoration[], messageDecoration: MessageDecoration): void {
for (let [i, decoration] of list.entries()) {
if ((messageDecoration.priority || 0) < (decoration.priority || 0)) {
list.splice(i, 0, messageDecoration);
return;
}
}
list.push(messageDecoration);
}
}

0 comments on commit 9a53e81

Please sign in to comment.