99
1010import { Config } from '@athenna/config'
1111import { Driver } from '#src/drivers/Driver'
12- import { Color , Macroable } from '@athenna/common'
12+ import { Color , Json , Macroable } from '@athenna/common'
1313import { DriverFactory } from '#src/factories/DriverFactory'
1414import { VANILLA_CHANNELS } from '#src/constants/VanillaChannels'
1515
@@ -24,6 +24,21 @@ export class Logger extends Macroable {
2424 */
2525 private runtimeConfigs = { }
2626
27+ /**
28+ * Default message content that should be included
29+ * in every structured log emitted by this instance.
30+ */
31+ private messageDefaults = { }
32+
33+ /**
34+ * Store the current logger strategy so create()
35+ * can clone the logger preserving its behavior.
36+ */
37+ private selection : { type : 'channel' | 'vanilla' ; values : any [ ] } = {
38+ type : 'vanilla' ,
39+ values : [ ]
40+ }
41+
2742 public constructor ( ) {
2843 super ( )
2944 this . channelOrVanilla ( Config . get ( 'logging.default' ) )
@@ -52,14 +67,36 @@ export class Logger extends Macroable {
5267 return this
5368 }
5469
70+ /**
71+ * Create a new logger instance inheriting the current
72+ * configuration and adding default message content.
73+ */
74+ public create ( defaults : any = { } ) : Logger {
75+ const logger = new Logger ( )
76+
77+ logger . runtimeConfigs = Json . copy ( this . runtimeConfigs )
78+ logger . messageDefaults = {
79+ ...Json . copy ( this . messageDefaults ) ,
80+ ...Json . copy ( defaults || { } )
81+ }
82+
83+ return logger [ this . selection . type ] ( ...Json . copy ( this . selection . values ) )
84+ }
85+
5586 /**
5687 * Change the log channel.
5788 */
5889 public channel ( ...channels : string [ ] ) : Logger {
5990 this . drivers = [ ]
91+ this . selection = {
92+ type : 'channel' ,
93+ values : [ ...channels ]
94+ }
95+
96+ const runtimeConfigs = this . withDefaultFormatterConfig ( this . runtimeConfigs )
6097
6198 channels . forEach ( channel => {
62- this . drivers . push ( DriverFactory . fabricate ( channel , this . runtimeConfigs ) )
99+ this . drivers . push ( DriverFactory . fabricate ( channel , runtimeConfigs ) )
63100 } )
64101
65102 return this
@@ -72,15 +109,23 @@ export class Logger extends Macroable {
72109 */
73110 public vanilla ( ...configs : any [ ] ) : Logger {
74111 this . drivers = [ ]
112+ this . selection = {
113+ type : 'vanilla' ,
114+ values : Json . copy ( configs )
115+ }
75116
76117 if ( ! configs . length ) {
77- this . drivers . push ( DriverFactory . fabricateVanilla ( ) )
118+ this . drivers . push (
119+ DriverFactory . fabricateVanilla ( this . withDefaultFormatterConfig ( ) )
120+ )
78121
79122 return this
80123 }
81124
82125 configs . forEach ( config => {
83- this . drivers . push ( DriverFactory . fabricateVanilla ( config ) )
126+ this . drivers . push (
127+ DriverFactory . fabricateVanilla ( this . withDefaultFormatterConfig ( config ) )
128+ )
84129 } )
85130
86131 return this
@@ -171,4 +216,25 @@ export class Logger extends Macroable {
171216
172217 return Promise . all ( promises )
173218 }
219+
220+ /**
221+ * Attach message defaults to formatter configs so
222+ * structured formatters can enrich the output.
223+ */
224+ private withDefaultFormatterConfig ( configs : any = { } ) : any {
225+ if ( ! Object . keys ( this . messageDefaults ) . length ) {
226+ return configs
227+ }
228+
229+ return {
230+ ...configs ,
231+ formatterConfig : {
232+ ...( configs . formatterConfig || { } ) ,
233+ defaults : {
234+ ...( ( configs . formatterConfig || { } ) . defaults || { } ) ,
235+ ...this . messageDefaults
236+ }
237+ }
238+ }
239+ }
174240}
0 commit comments