@athenna/logger 1.2.8 → 1.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/index.js CHANGED
@@ -1,31 +1,34 @@
1
- import Chalk from 'chalk'
1
+ import { Chalk } from 'chalk'
2
+ import { Is } from '@secjs/utils'
3
+ import { format } from 'node:util'
2
4
 
3
- import { Is, Options } from '@secjs/utils'
4
-
5
- import { ColorHelper } from '#src/Helpers/ColorHelper'
6
5
  import { DriverFactory } from '#src/Factories/DriverFactory'
7
- import { FormatterFactory } from '#src/Factories/FormatterFactory'
8
6
 
9
7
  export * from './Facades/Log.js'
8
+
10
9
  export * from './Helpers/ColorHelper.js'
11
10
  export * from './Helpers/FactoryHelper.js'
11
+
12
+ export * from './Drivers/Driver.js'
13
+ export * from './Formatters/Formatter.js'
14
+
12
15
  export * from './Factories/DriverFactory.js'
13
16
  export * from './Factories/FormatterFactory.js'
14
17
 
15
18
  export class Logger {
16
19
  /**
17
- * Runtime configurations to be used inside the Drivers and Formatters.
20
+ * The driver responsible for transporting the logs.
18
21
  *
19
- * @type {any}
22
+ * @type {any[]}
20
23
  */
21
- #runtimeConfig = {}
24
+ #drivers = []
22
25
 
23
26
  /**
24
- * The driver responsible for transporting the logs.
27
+ * Runtime configurations to be used inside the Drivers and Formatters.
25
28
  *
26
- * @type {any[]}
29
+ * @type {any}
27
30
  */
28
- #drivers = []
31
+ #runtimeConfigs = {}
29
32
 
30
33
  /**
31
34
  * Creates a new instance of Logger.
@@ -33,229 +36,163 @@ export class Logger {
33
36
  * @return {Logger}
34
37
  */
35
38
  constructor() {
36
- this.#drivers.push(DriverFactory.fabricate('default', this.#runtimeConfig))
39
+ this.#drivers.push(DriverFactory.fabricate('default', this.#runtimeConfigs))
37
40
  }
38
41
 
39
42
  /**
40
- * Return all drivers available.
43
+ * Set runtime configurations for drivers and
44
+ * formatters.
41
45
  *
42
- * @return {string[]}
46
+ * @param {any} runtimeConfigs
47
+ * @return {Logger}
43
48
  */
44
- static get drivers() {
45
- return DriverFactory.availableDrivers()
46
- }
49
+ config(runtimeConfigs) {
50
+ this.#runtimeConfigs = runtimeConfigs
47
51
 
48
- /**
49
- * Return all formatters available.
50
- *
51
- * @return {string[]}
52
- */
53
- static get formatters() {
54
- return FormatterFactory.availableFormatters()
52
+ return this
55
53
  }
56
54
 
57
55
  /**
58
- * Applies the log engine to execute chalk methods of string.
56
+ * Change the log channel.
59
57
  *
60
- * @param {string} content
58
+ * @param {string} channels
59
+ * @return {Logger}
61
60
  */
62
- static #applyLogEngine(content) {
63
- if (Is.String(content)) {
64
- const matches = content.match(/\({(.*?)} (.*?)\)/)
65
-
66
- if (matches) {
67
- const chalkMethodsString = matches[1].replace(/\s/g, '')
68
- const chalkMethodsArray = chalkMethodsString.split(',')
69
- const message = matches[2]
70
-
71
- let chalk = Chalk
72
-
73
- chalkMethodsArray.forEach(chalkMethod => {
74
- if (!chalk[chalkMethod]) return
75
-
76
- chalk = chalk[chalkMethod]
77
- })
78
-
79
- content = content
80
- .replace(`({${matches[1]}} `, '')
81
- .replace(`({${matches[1]}}`, '')
82
- .replace(`${matches[2]})`, chalk(message))
83
- }
61
+ channel(...channels) {
62
+ this.#drivers = []
84
63
 
85
- return content
86
- }
64
+ channels.forEach(c => {
65
+ this.#drivers.push(DriverFactory.fabricate(c, this.#runtimeConfigs))
66
+ })
87
67
 
88
- return content
68
+ return this
89
69
  }
90
70
 
91
71
  /**
92
- * Transport the log.
72
+ * Call drivers to transport the log.
93
73
  *
94
- * @param {string|any} message
95
- * @param {any} [options]
96
- * @param {any} [defaultValues]
97
- * @return {void | Promise<void>}
74
+ * @param {string} level
75
+ * @param {string} args
76
+ * @return {any | Promise<any>}
98
77
  */
99
- #log(message, options = {}, defaultValues = {}) {
100
- options = this.#createOptions(options, defaultValues)
78
+ #log(level, ...args) {
79
+ const message = this.#applyEngine(...args)
101
80
 
102
- message = Logger.#applyLogEngine(message)
103
-
104
- const promises = this.#drivers.map(d => d.transport(message, options))
81
+ const promises = this.#drivers.map(d => d.transport(level, message))
105
82
 
106
83
  return Promise.all(promises)
107
84
  }
108
85
 
109
86
  /**
110
- * Create options concatenating client options with default options.
87
+ * Creates a log of type trace in channel.
111
88
  *
112
- * @param {any} options
113
- * @param {any} defaultValues
114
- * @return {any}
89
+ * @param {string|any} args
90
+ * @return {any | Promise<any>}
115
91
  */
116
- #createOptions(options, defaultValues) {
117
- let formatterConfig = Options.create(
118
- options.formatterConfig,
119
- defaultValues.formatterConfig,
120
- )
121
-
122
- if (this.#runtimeConfig.formatterConfig) {
123
- formatterConfig = {
124
- ...this.#runtimeConfig.formatterConfig,
125
- ...formatterConfig,
126
- }
127
- }
128
-
129
- options = {
130
- ...options,
131
- formatterConfig,
132
- }
133
-
134
- return options
92
+ trace(...args) {
93
+ return this.#log('trace', ...args)
135
94
  }
136
95
 
137
96
  /**
138
- * Set runtime configurations for drivers and
139
- * formatters.
97
+ * Creates a log of type debug in channel.
140
98
  *
141
- * @param {any} runtimeConfig
142
- * @return {Logger}
99
+ * @param {string|any} args
100
+ * @return {any | Promise<any>}
143
101
  */
144
- config(runtimeConfig) {
145
- this.#runtimeConfig = runtimeConfig
146
-
147
- return this
102
+ debug(...args) {
103
+ return this.#log('debug', ...args)
148
104
  }
149
105
 
150
106
  /**
151
- * Change the log channel.
107
+ * Creates a log of type info in channel.
152
108
  *
153
- * @param {string[]} channels
154
- * @return {Logger}
109
+ * @param {string|any} args
110
+ * @return {any | Promise<any>}
155
111
  */
156
- channel(...channels) {
157
- this.#drivers = []
158
-
159
- channels.forEach(channel => {
160
- this.#drivers.push(DriverFactory.fabricate(channel, this.#runtimeConfig))
161
- })
162
-
163
- return this
112
+ info(...args) {
113
+ return this.#log('info', ...args)
164
114
  }
165
115
 
166
116
  /**
167
- * Creates a log of type info in channel.
117
+ * Creates a log of type success in channel.
168
118
  *
169
- * @param {string|any} message
170
- * @param {any} [options]
171
- * @return {void | Promise<void>}
119
+ * @param {string|any} args
120
+ * @return {any | Promise<any>}
172
121
  */
173
- info(message, options = {}) {
174
- return this.#log(message, options, {
175
- formatterConfig: {
176
- level: 'INFO',
177
- chalk: ColorHelper.cyan,
178
- },
179
- })
122
+ success(...args) {
123
+ return this.#log('success', ...args)
180
124
  }
181
125
 
182
126
  /**
183
127
  * Creates a log of type warn in channel.
184
128
  *
185
- * @param {string|any} message
186
- * @param {any} [options]
187
- * @return {void | Promise<void>}
129
+ * @param {string|any} args
130
+ * @return {any | Promise<any>}
188
131
  */
189
- warn(message, options = {}) {
190
- return this.#log(message, options, {
191
- formatterConfig: {
192
- level: 'WARN',
193
- chalk: ColorHelper.orange,
194
- },
195
- })
132
+ warn(...args) {
133
+ return this.#log('warn', ...args)
196
134
  }
197
135
 
198
136
  /**
199
137
  * Creates a log of type error in channel.
200
138
  *
201
- * @param {string|any} message
202
- * @param {any} [options]
203
- * @return {void | Promise<void>}
139
+ * @param {string|any} args
140
+ * @return {any | Promise<any>}
204
141
  */
205
- error(message, options = {}) {
206
- return this.#log(message, options, {
207
- formatterConfig: {
208
- level: 'ERROR',
209
- chalk: ColorHelper.red,
210
- },
211
- })
142
+ error(...args) {
143
+ return this.#log('error', ...args)
212
144
  }
213
145
 
214
146
  /**
215
- * Creates a log of type critical in channel.
147
+ * Creates a log of type fatal in channel.
216
148
  *
217
- * @param {string|any} message
218
- * @param {any} [options]
219
- * @return {void | Promise<void>}
149
+ * @param {string|any} args
150
+ * @return {any | Promise<any>}
220
151
  */
221
- critical(message, options = {}) {
222
- return this.#log(message, options, {
223
- formatterConfig: {
224
- level: 'CRITICAL',
225
- chalk: ColorHelper.darkRed,
226
- },
227
- })
152
+ fatal(...args) {
153
+ return this.#log('fatal', ...args)
228
154
  }
229
155
 
230
156
  /**
231
- * Creates a log of type debug in channel.
157
+ * Applies the log engine to execute chalk methods.
232
158
  *
233
- * @param {string|any} message
234
- * @param {any} [options]
235
- * @return {void | Promise<void>}
159
+ * @param {string} args
160
+ * @return {any}
236
161
  */
237
- debug(message, options = {}) {
238
- return this.#log(message, options, {
239
- formatterConfig: {
240
- level: 'DEBUG',
241
- chalk: ColorHelper.purple,
242
- },
243
- })
244
- }
162
+ #applyEngine(...args) {
163
+ if (!Is.String(args[0])) {
164
+ return args[0]
165
+ }
245
166
 
246
- /**
247
- * Creates a log of type success in channel.
248
- *
249
- * @param {string|any} message
250
- * @param {any} [options]
251
- * @return {void | Promise<void>}
252
- */
253
- success(message, options = {}) {
254
- return this.#log(message, options, {
255
- formatterConfig: {
256
- level: 'SUCCESS',
257
- chalk: ColorHelper.green,
258
- },
167
+ let content = format(...args)
168
+
169
+ const matches = content.match(/\({(.*?)} (.*?)\)/g)
170
+
171
+ if (!matches) {
172
+ return content
173
+ }
174
+
175
+ matches.forEach(match => {
176
+ const [chalkMethodsInBrackets, chalkMethodsString] =
177
+ match.match(/\{(.*?)\}/)
178
+
179
+ const message = match
180
+ .replace(chalkMethodsInBrackets, '')
181
+ .replace(/\s*\(\s*|\s*\)\s*/g, '')
182
+
183
+ const chalkMethodsArray = chalkMethodsString.replace(/\s/g, '').split(',')
184
+
185
+ let chalk = new Chalk()
186
+
187
+ chalkMethodsArray.forEach(chalkMethod => {
188
+ if (!chalk[chalkMethod]) return
189
+
190
+ chalk = chalk[chalkMethod]
191
+ })
192
+
193
+ content = content.replace(match, chalk(message))
259
194
  })
195
+
196
+ return content
260
197
  }
261
198
  }
@@ -1,54 +0,0 @@
1
- /**
2
- * @athenna/logger
3
- *
4
- * (c) João Lenon <lenon@athenna.io>
5
- *
6
- * For the full copyright and license information, please view the LICENSE
7
- * file that was distributed with this source code.
8
- */
9
-
10
- import debug from 'debug'
11
-
12
- import { Config } from '@secjs/utils'
13
-
14
- import { FactoryHelper, FormatterFactory } from '#src/index'
15
-
16
- export class DebugDriver {
17
- /**
18
- * Holds the configuration set of DebugDriver.
19
- *
20
- * @type {{ namespace?: string, formatter?: any, formatterConfig?: any }}
21
- */
22
- configs
23
-
24
- /**
25
- * Creates a new instance of DebugDriver.
26
- *
27
- * @param {string} channel
28
- * @param {any} [configs]
29
- * @return {DebugDriver}
30
- */
31
- constructor(channel, configs = {}) {
32
- const channelConfig = Config.get(`logging.channels.${channel}`)
33
-
34
- this.configs = FactoryHelper.groupConfigs(configs, channelConfig)
35
- }
36
-
37
- /**
38
- * Transport the log.
39
- *
40
- * @param {string} message
41
- * @param {{ namespace?: string, formatter?: any, formatterConfig?: any }} [options]
42
- * @return {void}
43
- */
44
- transport(message, options = {}) {
45
- const configs = FactoryHelper.groupConfigs(options, this.configs)
46
-
47
- message = FormatterFactory.fabricate(configs.formatter).format(
48
- message,
49
- configs.formatterConfig,
50
- )
51
-
52
- debug(configs.namespace)(message)
53
- }
54
- }
@@ -1,94 +0,0 @@
1
- /**
2
- * @athenna/logger
3
- *
4
- * (c) João Lenon <lenon@athenna.io>
5
- *
6
- * For the full copyright and license information, please view the LICENSE
7
- * file that was distributed with this source code.
8
- */
9
-
10
- import pino from 'pino'
11
-
12
- import { Config } from '@secjs/utils'
13
-
14
- import { FactoryHelper } from '#src/index'
15
- import { OnlyPinoPrettyException } from '#src/Exceptions/OnlyPinoPrettyException'
16
-
17
- export class PinoDriver {
18
- /**
19
- * Holds the configuration set of PinoDriver.
20
- *
21
- * @type {import('pino').LoggerOptions & { formatter?: 'pino-pretty', formatterConfig?: import('pino-pretty').PrettyOptions }}
22
- */
23
- configs
24
-
25
- /**
26
- * Creates a new instance of PinoDriver.
27
- *
28
- * @param {string} channel
29
- * @param {any} [configs]
30
- * @return {PinoDriver}
31
- */
32
- constructor(channel, configs = {}) {
33
- const channelConfig = Config.get(`logging.channels.${channel}`)
34
-
35
- this.configs = FactoryHelper.groupConfigs(configs, channelConfig)
36
- }
37
-
38
- /**
39
- * Transport the log.
40
- *
41
- * @param {string} message
42
- * @param {import('pino').LoggerOptions & { formatter?: 'pino-pretty', formatterConfig?: import('pino-pretty').PrettyOptions }} [options]
43
- * @return {void}
44
- */
45
- transport(message, options = {}) {
46
- const configs = FactoryHelper.groupConfigs(options, this.configs)
47
-
48
- configs.customLevels = {
49
- info: 1,
50
- warn: 2,
51
- error: 3,
52
- debug: 4,
53
- success: 5,
54
- critical: 6,
55
- }
56
- configs.useOnlyCustomLevels = true
57
-
58
- const pinoMethod = configs.formatterConfig.level.toLowerCase()
59
-
60
- delete configs.formatterConfig.level
61
- delete configs.formatterConfig.chalk
62
-
63
- if (configs.formatter !== 'pino-pretty') {
64
- throw new OnlyPinoPrettyException()
65
- }
66
-
67
- const pinoConfigs = {}
68
-
69
- Object.keys(configs).forEach(key => {
70
- if (key === 'formatter') {
71
- pinoConfigs.transport = {
72
- target: 'pino-pretty',
73
- options: configs.formatterConfig,
74
- }
75
- configs.formatterConfig.customLevels =
76
- 'info:1,warn:2,error:3,debug:4,success:5,critical:6'
77
- configs.formatterConfig.customColors =
78
- 'info:cyan,warn:yellow,error:red,debug:magenta,success:green,critical:red'
79
-
80
- return
81
- }
82
-
83
- if (['driver', 'formatterConfig'].includes(key)) {
84
- return
85
- }
86
-
87
- pinoConfigs[key] = configs[key]
88
- })
89
-
90
- const logger = pino(pinoConfigs)
91
-
92
- logger[pinoMethod](message)
93
- }
94
- }
@@ -1,32 +0,0 @@
1
- /**
2
- * @athenna/logger
3
- *
4
- * (c) João Lenon <lenon@athenna.io>
5
- *
6
- * For the full copyright and license information, please view the LICENSE
7
- * file that was distributed with this source code.
8
- */
9
-
10
- import { Config, Exception } from '@secjs/utils'
11
-
12
- export class NotFoundChannelException extends Exception {
13
- /**
14
- * Creates a new instance of NotFoundChannelException.
15
- *
16
- * @param {string} channelName
17
- * @return {NotFoundChannelException}
18
- */
19
- constructor(channelName) {
20
- const content = `Channel ${channelName} not found.`
21
- const availableChannels = Object.keys(Config.get('logging.channels')).join(
22
- ', ',
23
- )
24
-
25
- super(
26
- content,
27
- 500,
28
- 'E_NOT_FOUND',
29
- `Available channels are: ${availableChannels}. Look into your config/logger file if ${channelName} channel is inside "channels" property, if it does not exist create ${channelName} channel object inside "channels".`,
30
- )
31
- }
32
- }
@@ -1,28 +0,0 @@
1
- /**
2
- * @athenna/logger
3
- *
4
- * (c) João Lenon <lenon@athenna.io>
5
- *
6
- * For the full copyright and license information, please view the LICENSE
7
- * file that was distributed with this source code.
8
- */
9
-
10
- import { Exception } from '@secjs/utils'
11
-
12
- export class OnlyPinoPrettyException extends Exception {
13
- /**
14
- * Creates a new instance of OnlyPinoPrettyException.
15
- *
16
- * @return {OnlyPinoPrettyException}
17
- */
18
- constructor() {
19
- const content = `The driver "pino" can only be used with "pino-pretty" formatter.`
20
-
21
- super(
22
- content,
23
- 500,
24
- 'E_PINO_PRETTY',
25
- `Available formatters are: pino-pretty. Look into your config/logger file where your are using "pino" driver and change the formatter to pino-pretty.`,
26
- )
27
- }
28
- }
@@ -1,40 +0,0 @@
1
- /**
2
- * @athenna/logger
3
- *
4
- * (c) João Lenon <lenon@athenna.io>
5
- *
6
- * For the full copyright and license information, please view the LICENSE
7
- * file that was distributed with this source code.
8
- */
9
-
10
- import { ColorHelper, FactoryHelper } from '#src/index'
11
-
12
- export class NestFormatter {
13
- /**
14
- * The last timestamp.
15
- *
16
- * @type {number}
17
- */
18
- #lastTimestamp
19
-
20
- /**
21
- * Format the message.
22
- *
23
- * @param {string} message
24
- * @param {{ context: string, chalk: import('chalk').ChalkInstance }} options
25
- * @return {string}
26
- */
27
- format(message, options) {
28
- const timestampDiff = FactoryHelper.getTimestampDiff(this.#lastTimestamp)
29
-
30
- this.#lastTimestamp = Date.now()
31
-
32
- const pid = ColorHelper.yellow(`[Athenna] - PID: ${process.pid}`)
33
- const timestamp = FactoryHelper.getTimestamp()
34
- const messageCtx = ColorHelper.yellow(`[${options.context}] `)
35
-
36
- return `${pid} - ${timestamp} ${messageCtx}${options.chalk(
37
- message,
38
- )}${timestampDiff}`
39
- }
40
- }