| ... | @@ -80,7 +80,7 @@ export interface Scope { | ... | @@ -80,7 +80,7 @@ export interface Scope { |
| 80 | writeMessage(message: Message): void; | 80 | writeMessage(message: Message): void; |
| 81 | | 81 | |
| 82 | /** create a nested sub-scope */ | 82 | /** create a nested sub-scope */ |
| 83 | scoped(name: string): Scope; | 83 | scoped(name: string, custom?: Message["custom"]): Scope; |
| 84 | /** redirect the logging output of this scope somewhere else */ | 84 | /** redirect the logging output of this scope somewhere else */ |
| 85 | tee(writer: (message: Message) => void): ts.Dispose; | 85 | tee(writer: (message: Message) => void): ts.Dispose; |
| 86 | } | 86 | } |
| ... | @@ -154,9 +154,9 @@ export function log(...args: unknown[]) { | ... | @@ -154,9 +154,9 @@ export function log(...args: unknown[]) { |
| 154 | export function debug(...args: unknown[]) { | 154 | export function debug(...args: unknown[]) { |
| 155 | globalLog.debug(...args); | 155 | globalLog.debug(...args); |
| 156 | } | 156 | } |
| 157 | /** create a named logging scope */ | 157 | /** create a named logging scope, optionally carrying custom message fields */ |
| 158 | export function scoped(name: string): Scope { | 158 | export function scoped(name: string, custom?: Message["custom"]): Scope { |
| 159 | return globalLog.scoped(name); | 159 | return globalLog.scoped(name, custom); |
| 160 | } | 160 | } |
| 161 | /** redirect all log messages to another writer */ | 161 | /** redirect all log messages to another writer */ |
| 162 | export function tee(destination: DispatchFunction): ts.Dispose { | 162 | export function tee(destination: DispatchFunction): ts.Dispose { |
| ... | @@ -1058,6 +1058,8 @@ let withinStackCapture = false; | ... | @@ -1058,6 +1058,8 @@ let withinStackCapture = false; |
| 1058 | /** this class is an implementation detail */ | 1058 | /** this class is an implementation detail */ |
| 1059 | const ScopeImpl = class Scope implements RootScope { | 1059 | const ScopeImpl = class Scope implements RootScope { |
| 1060 | name: string | undefined; | 1060 | name: string | undefined; |
| | 1061 | /** attached to every emitted message; see `Scope.scoped` */ |
| | 1062 | #custom: Message["custom"]; |
| 1061 | // TODO: this abstraction implementation has low performance. making every | 1063 | // TODO: this abstraction implementation has low performance. making every |
| 1062 | // scope define it's own dispatch is needed to correctly implement `tee`. | 1064 | // scope define it's own dispatch is needed to correctly implement `tee`. |
| 1063 | // since it is possible to implement this in simple and non-recursive way, i | 1065 | // since it is possible to implement this in simple and non-recursive way, i |
| ... | @@ -1068,8 +1070,10 @@ const ScopeImpl = class Scope implements RootScope { | ... | @@ -1068,8 +1070,10 @@ const ScopeImpl = class Scope implements RootScope { |
| 1068 | constructor( | 1070 | constructor( |
| 1069 | dispatch: (m: Message) => void, | 1071 | dispatch: (m: Message) => void, |
| 1070 | name: string | undefined = undefined, | 1072 | name: string | undefined = undefined, |
| | 1073 | custom: Message["custom"] = undefined, |
| 1071 | ) { | 1074 | ) { |
| 1072 | this.name = name; | 1075 | this.name = name; |
| | 1076 | this.#custom = custom; |
| 1073 | this.#dispatches = [dispatch]; | 1077 | this.#dispatches = [dispatch]; |
| 1074 | } | 1078 | } |
| 1075 | | 1079 | |
| ... | @@ -1083,6 +1087,7 @@ const ScopeImpl = class Scope implements RootScope { | ... | @@ -1083,6 +1087,7 @@ const ScopeImpl = class Scope implements RootScope { |
| 1083 | this.writeMessage({ | 1087 | this.writeMessage({ |
| 1084 | level, | 1088 | level, |
| 1085 | scope: this.name, | 1089 | scope: this.name, |
| | 1090 | custom: this.#custom, |
| 1086 | get text() { | 1091 | get text() { |
| 1087 | const value = formatLine(...args); | 1092 | const value = formatLine(...args); |
| 1088 | Object.defineProperty(this, "text", { value }); | 1093 | Object.defineProperty(this, "text", { value }); |
| ... | @@ -1127,6 +1132,7 @@ const ScopeImpl = class Scope implements RootScope { | ... | @@ -1127,6 +1132,7 @@ const ScopeImpl = class Scope implements RootScope { |
| 1127 | this.writeMessage({ | 1132 | this.writeMessage({ |
| 1128 | level: "info", | 1133 | level: "info", |
| 1129 | scope: "", | 1134 | scope: "", |
| | 1135 | custom: this.#custom, |
| 1130 | newline: false, | 1136 | newline: false, |
| 1131 | text, | 1137 | text, |
| 1132 | time: Date.now(), | 1138 | time: Date.now(), |
| ... | @@ -1134,11 +1140,12 @@ const ScopeImpl = class Scope implements RootScope { | ... | @@ -1134,11 +1140,12 @@ const ScopeImpl = class Scope implements RootScope { |
| 1134 | }); | 1140 | }); |
| 1135 | }; | 1141 | }; |
| 1136 | | 1142 | |
| 1137 | scoped(name: string): Scope { | 1143 | scoped(name: string, custom?: Message["custom"]): Scope { |
| 1138 | const current = this.name; | 1144 | const current = this.name; |
| 1139 | return new Scope( | 1145 | return new Scope( |
| 1140 | this.#dispatch, | 1146 | this.#dispatch, |
| 1141 | name ? current ? `${current}/${name}` : name : current, | 1147 | name ? current ? `${current}/${name}` : name : current, |
| | 1148 | custom ? { ...this.#custom, ...custom } : this.#custom, |
| 1142 | ); | 1149 | ); |
| 1143 | } | 1150 | } |
| 1144 | | 1151 | |