create-fluxstack 1.1.0 → 1.4.1
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/app/server/backend-only.ts +5 -5
- package/app/server/index.ts +63 -54
- package/app/server/live/FluxStackConfig.ts +43 -39
- package/app/server/live/SystemMonitorIntegration.ts +2 -2
- package/app/server/live/register-components.ts +1 -1
- package/app/server/middleware/errorHandling.ts +6 -4
- package/app/server/routes/config.ts +145 -0
- package/app/server/routes/index.ts +5 -3
- package/config/app.config.ts +113 -0
- package/config/build.config.ts +24 -0
- package/config/database.config.ts +99 -0
- package/config/index.ts +68 -0
- package/config/logger.config.ts +27 -0
- package/config/runtime.config.ts +92 -0
- package/config/server.config.ts +46 -0
- package/config/services.config.ts +130 -0
- package/config/system.config.ts +105 -0
- package/core/build/index.ts +10 -4
- package/core/cli/generators/index.ts +5 -2
- package/core/cli/generators/plugin.ts +290 -0
- package/core/cli/index.ts +117 -15
- package/core/config/env.ts +37 -95
- package/core/config/runtime-config.ts +61 -58
- package/core/config/schema.ts +4 -0
- package/core/framework/server.ts +22 -10
- package/core/plugins/built-in/index.ts +7 -17
- package/core/plugins/built-in/swagger/index.ts +228 -228
- package/core/plugins/built-in/vite/index.ts +374 -358
- package/core/plugins/dependency-manager.ts +5 -5
- package/core/plugins/manager.ts +12 -12
- package/core/plugins/registry.ts +3 -3
- package/core/server/index.ts +0 -1
- package/core/server/live/ComponentRegistry.ts +34 -8
- package/core/server/live/LiveComponentPerformanceMonitor.ts +1 -1
- package/core/server/live/websocket-plugin.ts +434 -434
- package/core/server/middleware/README.md +488 -0
- package/core/server/middleware/elysia-helpers.ts +227 -0
- package/core/server/middleware/index.ts +25 -9
- package/core/server/plugins/static-files-plugin.ts +231 -231
- package/core/utils/config-schema.ts +484 -0
- package/core/utils/env.ts +306 -0
- package/core/utils/helpers.ts +4 -4
- package/core/utils/logger/colors.ts +114 -0
- package/core/utils/logger/config.ts +35 -0
- package/core/utils/logger/formatter.ts +82 -0
- package/core/utils/logger/group-logger.ts +101 -0
- package/core/utils/logger/index.ts +199 -250
- package/core/utils/logger/stack-trace.ts +92 -0
- package/core/utils/logger/startup-banner.ts +92 -0
- package/core/utils/logger/winston-logger.ts +152 -0
- package/core/utils/version.ts +5 -0
- package/create-fluxstack.ts +118 -8
- package/fluxstack.config.ts +2 -2
- package/package.json +117 -115
- package/core/config/env-dynamic.ts +0 -326
- package/core/plugins/built-in/logger/index.ts +0 -180
- package/core/server/plugins/logger.ts +0 -47
- package/core/utils/env-runtime-v2.ts +0 -232
- package/core/utils/env-runtime.ts +0 -259
- package/core/utils/logger/formatters.ts +0 -222
- package/core/utils/logger/middleware.ts +0 -253
- package/core/utils/logger/performance.ts +0 -384
- package/core/utils/logger/transports.ts +0 -365
- package/core/utils/logger.ts +0 -106
|
@@ -1,365 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* FluxStack Logger Transports
|
|
3
|
-
* Multiple transport implementations for different logging needs
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { writeFile, mkdir, stat, readdir, unlink } from 'fs/promises'
|
|
7
|
-
import { join, dirname } from 'path'
|
|
8
|
-
import { createGzip } from 'zlib'
|
|
9
|
-
import { pipeline } from 'stream/promises'
|
|
10
|
-
import { createReadStream, createWriteStream } from 'fs'
|
|
11
|
-
|
|
12
|
-
export type LogLevel = 'debug' | 'info' | 'warn' | 'error'
|
|
13
|
-
|
|
14
|
-
export interface LogEntry {
|
|
15
|
-
timestamp: string
|
|
16
|
-
level: LogLevel
|
|
17
|
-
message: string
|
|
18
|
-
meta?: any
|
|
19
|
-
context?: any
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export interface LogTransport {
|
|
23
|
-
name: string
|
|
24
|
-
level: LogLevel
|
|
25
|
-
write(entry: LogEntry): Promise<void> | void
|
|
26
|
-
close?(): Promise<void> | void
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export interface ConsoleTransportConfig {
|
|
30
|
-
level?: LogLevel
|
|
31
|
-
colors?: boolean
|
|
32
|
-
timestamp?: boolean
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export interface FileTransportConfig {
|
|
36
|
-
level?: LogLevel
|
|
37
|
-
filename: string
|
|
38
|
-
maxSize?: number // in bytes
|
|
39
|
-
maxFiles?: number
|
|
40
|
-
compress?: boolean
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export interface JSONTransportConfig {
|
|
44
|
-
level?: LogLevel
|
|
45
|
-
filename?: string
|
|
46
|
-
pretty?: boolean
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Console Transport with colored output for development
|
|
51
|
-
*/
|
|
52
|
-
export class ConsoleTransport implements LogTransport {
|
|
53
|
-
name = 'console'
|
|
54
|
-
level: LogLevel
|
|
55
|
-
private colors: boolean
|
|
56
|
-
private timestamp: boolean
|
|
57
|
-
|
|
58
|
-
private colorMap = {
|
|
59
|
-
debug: '\x1b[36m', // cyan
|
|
60
|
-
info: '\x1b[32m', // green
|
|
61
|
-
warn: '\x1b[33m', // yellow
|
|
62
|
-
error: '\x1b[31m', // red
|
|
63
|
-
reset: '\x1b[0m'
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
constructor(config: ConsoleTransportConfig = {}) {
|
|
67
|
-
this.level = config.level || 'info'
|
|
68
|
-
this.colors = config.colors !== false
|
|
69
|
-
this.timestamp = config.timestamp !== false
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
private shouldLog(level: LogLevel): boolean {
|
|
73
|
-
const levels: Record<LogLevel, number> = {
|
|
74
|
-
debug: 0,
|
|
75
|
-
info: 1,
|
|
76
|
-
warn: 2,
|
|
77
|
-
error: 3
|
|
78
|
-
}
|
|
79
|
-
return levels[level] >= levels[this.level]
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
private formatMessage(entry: LogEntry): string {
|
|
83
|
-
const { timestamp, level, message, meta, context } = entry
|
|
84
|
-
|
|
85
|
-
let formatted = ''
|
|
86
|
-
|
|
87
|
-
// Add timestamp
|
|
88
|
-
if (this.timestamp) {
|
|
89
|
-
const color = this.colors ? '\x1b[90m' : '' // gray
|
|
90
|
-
const reset = this.colors ? this.colorMap.reset : ''
|
|
91
|
-
formatted += `${color}[${timestamp}]${reset} `
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// Add level with color
|
|
95
|
-
const levelColor = this.colors ? this.colorMap[level] : ''
|
|
96
|
-
const reset = this.colors ? this.colorMap.reset : ''
|
|
97
|
-
const levelStr = level.toUpperCase().padEnd(5)
|
|
98
|
-
formatted += `${levelColor}${levelStr}${reset} `
|
|
99
|
-
|
|
100
|
-
// Add context if available
|
|
101
|
-
if (context && Object.keys(context).length > 0) {
|
|
102
|
-
const contextStr = Object.entries(context)
|
|
103
|
-
.map(([key, value]) => `${key}=${value}`)
|
|
104
|
-
.join(' ')
|
|
105
|
-
const contextColor = this.colors ? '\x1b[90m' : '' // gray
|
|
106
|
-
formatted += `${contextColor}[${contextStr}]${reset} `
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Add message
|
|
110
|
-
formatted += message
|
|
111
|
-
|
|
112
|
-
// Add meta if available
|
|
113
|
-
if (meta && typeof meta === 'object') {
|
|
114
|
-
const metaColor = this.colors ? '\x1b[90m' : '' // gray
|
|
115
|
-
formatted += ` ${metaColor}${JSON.stringify(meta)}${reset}`
|
|
116
|
-
} else if (meta !== undefined) {
|
|
117
|
-
formatted += ` ${meta}`
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
return formatted
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
write(entry: LogEntry): void {
|
|
124
|
-
if (!this.shouldLog(entry.level)) return
|
|
125
|
-
|
|
126
|
-
const formatted = this.formatMessage(entry)
|
|
127
|
-
|
|
128
|
-
// Use appropriate console method
|
|
129
|
-
switch (entry.level) {
|
|
130
|
-
case 'debug':
|
|
131
|
-
console.debug(formatted)
|
|
132
|
-
break
|
|
133
|
-
case 'info':
|
|
134
|
-
console.info(formatted)
|
|
135
|
-
break
|
|
136
|
-
case 'warn':
|
|
137
|
-
console.warn(formatted)
|
|
138
|
-
break
|
|
139
|
-
case 'error':
|
|
140
|
-
console.error(formatted)
|
|
141
|
-
break
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* File Transport with rotation and compression
|
|
148
|
-
*/
|
|
149
|
-
export class FileTransport implements LogTransport {
|
|
150
|
-
name = 'file'
|
|
151
|
-
level: LogLevel
|
|
152
|
-
private filename: string
|
|
153
|
-
private maxSize: number
|
|
154
|
-
private maxFiles: number
|
|
155
|
-
private compress: boolean
|
|
156
|
-
private currentSize = 0
|
|
157
|
-
|
|
158
|
-
constructor(config: FileTransportConfig) {
|
|
159
|
-
this.level = config.level || 'info'
|
|
160
|
-
this.filename = config.filename
|
|
161
|
-
this.maxSize = config.maxSize || 10 * 1024 * 1024 // 10MB default
|
|
162
|
-
this.maxFiles = config.maxFiles || 5
|
|
163
|
-
this.compress = config.compress !== false
|
|
164
|
-
|
|
165
|
-
this.ensureDirectory()
|
|
166
|
-
this.getCurrentSize()
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
private async ensureDirectory(): Promise<void> {
|
|
170
|
-
const dir = dirname(this.filename)
|
|
171
|
-
try {
|
|
172
|
-
await mkdir(dir, { recursive: true })
|
|
173
|
-
} catch (error) {
|
|
174
|
-
// Directory might already exist
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
private async getCurrentSize(): Promise<void> {
|
|
179
|
-
try {
|
|
180
|
-
const stats = await stat(this.filename)
|
|
181
|
-
this.currentSize = stats.size
|
|
182
|
-
} catch (error) {
|
|
183
|
-
this.currentSize = 0
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
private shouldLog(level: LogLevel): boolean {
|
|
188
|
-
const levels: Record<LogLevel, number> = {
|
|
189
|
-
debug: 0,
|
|
190
|
-
info: 1,
|
|
191
|
-
warn: 2,
|
|
192
|
-
error: 3
|
|
193
|
-
}
|
|
194
|
-
return levels[level] >= levels[this.level]
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
private formatMessage(entry: LogEntry): string {
|
|
198
|
-
const { timestamp, level, message, meta, context } = entry
|
|
199
|
-
|
|
200
|
-
let formatted = `[${timestamp}] ${level.toUpperCase().padEnd(5)}`
|
|
201
|
-
|
|
202
|
-
// Add context if available
|
|
203
|
-
if (context && Object.keys(context).length > 0) {
|
|
204
|
-
const contextStr = Object.entries(context)
|
|
205
|
-
.map(([key, value]) => `${key}=${value}`)
|
|
206
|
-
.join(' ')
|
|
207
|
-
formatted += ` [${contextStr}]`
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
formatted += ` ${message}`
|
|
211
|
-
|
|
212
|
-
// Add meta if available
|
|
213
|
-
if (meta && typeof meta === 'object') {
|
|
214
|
-
formatted += ` ${JSON.stringify(meta)}`
|
|
215
|
-
} else if (meta !== undefined) {
|
|
216
|
-
formatted += ` ${meta}`
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
return formatted + '\n'
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
private async rotateFile(): Promise<void> {
|
|
223
|
-
// Rotate existing files
|
|
224
|
-
for (let i = this.maxFiles - 1; i >= 1; i--) {
|
|
225
|
-
const oldFile = `${this.filename}.${i}`
|
|
226
|
-
const newFile = `${this.filename}.${i + 1}`
|
|
227
|
-
|
|
228
|
-
try {
|
|
229
|
-
await stat(oldFile)
|
|
230
|
-
if (i === this.maxFiles - 1) {
|
|
231
|
-
// Delete the oldest file
|
|
232
|
-
await unlink(oldFile)
|
|
233
|
-
} else {
|
|
234
|
-
// Rename to next number
|
|
235
|
-
const { rename } = await import('fs/promises')
|
|
236
|
-
await rename(oldFile, newFile)
|
|
237
|
-
}
|
|
238
|
-
} catch (error) {
|
|
239
|
-
// File doesn't exist, continue
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
// Move current file to .1
|
|
244
|
-
try {
|
|
245
|
-
await stat(this.filename)
|
|
246
|
-
const rotatedFile = `${this.filename}.1`
|
|
247
|
-
|
|
248
|
-
if (this.compress) {
|
|
249
|
-
// Compress the rotated file
|
|
250
|
-
await this.compressFile(this.filename, `${rotatedFile}.gz`)
|
|
251
|
-
await unlink(this.filename)
|
|
252
|
-
} else {
|
|
253
|
-
const { rename } = await import('fs/promises')
|
|
254
|
-
await rename(this.filename, rotatedFile)
|
|
255
|
-
}
|
|
256
|
-
} catch (error) {
|
|
257
|
-
// File doesn't exist, continue
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
this.currentSize = 0
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
private async compressFile(source: string, destination: string): Promise<void> {
|
|
264
|
-
const gzip = createGzip()
|
|
265
|
-
const sourceStream = createReadStream(source)
|
|
266
|
-
const destStream = createWriteStream(destination)
|
|
267
|
-
|
|
268
|
-
await pipeline(sourceStream, gzip, destStream)
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
async write(entry: LogEntry): Promise<void> {
|
|
272
|
-
if (!this.shouldLog(entry.level)) return
|
|
273
|
-
|
|
274
|
-
const formatted = this.formatMessage(entry)
|
|
275
|
-
const messageSize = Buffer.byteLength(formatted, 'utf8')
|
|
276
|
-
|
|
277
|
-
// Check if rotation is needed
|
|
278
|
-
if (this.currentSize + messageSize > this.maxSize) {
|
|
279
|
-
await this.rotateFile()
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
// Write to file
|
|
283
|
-
await writeFile(this.filename, formatted, { flag: 'a' })
|
|
284
|
-
this.currentSize += messageSize
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
async close(): Promise<void> {
|
|
288
|
-
// Nothing to close for file transport
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
/**
|
|
293
|
-
* JSON Transport for structured production logging
|
|
294
|
-
*/
|
|
295
|
-
export class JSONTransport implements LogTransport {
|
|
296
|
-
name = 'json'
|
|
297
|
-
level: LogLevel
|
|
298
|
-
private filename?: string
|
|
299
|
-
private pretty: boolean
|
|
300
|
-
|
|
301
|
-
constructor(config: JSONTransportConfig = {}) {
|
|
302
|
-
this.level = config.level || 'info'
|
|
303
|
-
this.filename = config.filename
|
|
304
|
-
this.pretty = config.pretty || false
|
|
305
|
-
|
|
306
|
-
if (this.filename) {
|
|
307
|
-
this.ensureDirectory()
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
private async ensureDirectory(): Promise<void> {
|
|
312
|
-
if (!this.filename) return
|
|
313
|
-
|
|
314
|
-
const dir = dirname(this.filename)
|
|
315
|
-
try {
|
|
316
|
-
await mkdir(dir, { recursive: true })
|
|
317
|
-
} catch (error) {
|
|
318
|
-
// Directory might already exist
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
private shouldLog(level: LogLevel): boolean {
|
|
323
|
-
const levels: Record<LogLevel, number> = {
|
|
324
|
-
debug: 0,
|
|
325
|
-
info: 1,
|
|
326
|
-
warn: 2,
|
|
327
|
-
error: 3
|
|
328
|
-
}
|
|
329
|
-
return levels[level] >= levels[this.level]
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
private formatEntry(entry: LogEntry): string {
|
|
333
|
-
const jsonEntry = {
|
|
334
|
-
timestamp: entry.timestamp,
|
|
335
|
-
level: entry.level,
|
|
336
|
-
message: entry.message,
|
|
337
|
-
...(entry.context && { context: entry.context }),
|
|
338
|
-
...(entry.meta && { meta: entry.meta })
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
const json = this.pretty
|
|
342
|
-
? JSON.stringify(jsonEntry, null, 2)
|
|
343
|
-
: JSON.stringify(jsonEntry)
|
|
344
|
-
|
|
345
|
-
return json + '\n'
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
async write(entry: LogEntry): Promise<void> {
|
|
349
|
-
if (!this.shouldLog(entry.level)) return
|
|
350
|
-
|
|
351
|
-
const formatted = this.formatEntry(entry)
|
|
352
|
-
|
|
353
|
-
if (this.filename) {
|
|
354
|
-
// Write to file
|
|
355
|
-
await writeFile(this.filename, formatted, { flag: 'a' })
|
|
356
|
-
} else {
|
|
357
|
-
// Write to console as JSON
|
|
358
|
-
process.stdout.write(formatted)
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
async close(): Promise<void> {
|
|
363
|
-
// Nothing to close for JSON transport
|
|
364
|
-
}
|
|
365
|
-
}
|
package/core/utils/logger.ts
DELETED
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* FluxStack Logger
|
|
3
|
-
* Environment-aware logging system
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
type LogLevel = 'debug' | 'info' | 'warn' | 'error'
|
|
7
|
-
|
|
8
|
-
class Logger {
|
|
9
|
-
private static instance: Logger | null = null
|
|
10
|
-
private logLevel: LogLevel
|
|
11
|
-
|
|
12
|
-
private constructor() {
|
|
13
|
-
this.logLevel = (process.env.LOG_LEVEL as LogLevel) || 'info'
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
static getInstance(): Logger {
|
|
17
|
-
if (Logger.instance === null) {
|
|
18
|
-
Logger.instance = new Logger()
|
|
19
|
-
}
|
|
20
|
-
return Logger.instance
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
private shouldLog(level: LogLevel): boolean {
|
|
24
|
-
const levels: Record<LogLevel, number> = {
|
|
25
|
-
debug: 0,
|
|
26
|
-
info: 1,
|
|
27
|
-
warn: 2,
|
|
28
|
-
error: 3
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
return levels[level] >= levels[this.logLevel]
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
private formatMessage(level: LogLevel, message: string, meta?: any): string {
|
|
35
|
-
const timestamp = new Date().toISOString()
|
|
36
|
-
const levelStr = level.toUpperCase().padEnd(5)
|
|
37
|
-
|
|
38
|
-
let formatted = `[${timestamp}] ${levelStr} ${message}`
|
|
39
|
-
|
|
40
|
-
if (meta && typeof meta === 'object') {
|
|
41
|
-
formatted += ` ${JSON.stringify(meta)}`
|
|
42
|
-
} else if (meta !== undefined) {
|
|
43
|
-
formatted += ` ${meta}`
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
return formatted
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
debug(message: string, meta?: any): void {
|
|
50
|
-
if (this.shouldLog('debug')) {
|
|
51
|
-
console.debug(this.formatMessage('debug', message, meta))
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
info(message: string, meta?: any): void {
|
|
56
|
-
if (this.shouldLog('info')) {
|
|
57
|
-
console.info(this.formatMessage('info', message, meta))
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
warn(message: string, meta?: any): void {
|
|
62
|
-
if (this.shouldLog('warn')) {
|
|
63
|
-
console.warn(this.formatMessage('warn', message, meta))
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
error(message: string, meta?: any): void {
|
|
68
|
-
if (this.shouldLog('error')) {
|
|
69
|
-
console.error(this.formatMessage('error', message, meta))
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// HTTP request logging
|
|
74
|
-
request(method: string, path: string, status?: number, duration?: number): void {
|
|
75
|
-
const statusStr = status ? ` ${status}` : ''
|
|
76
|
-
const durationStr = duration ? ` (${duration}ms)` : ''
|
|
77
|
-
this.info(`${method} ${path}${statusStr}${durationStr}`)
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// Plugin logging
|
|
81
|
-
plugin(pluginName: string, message: string, meta?: any): void {
|
|
82
|
-
this.debug(`[${pluginName}] ${message}`, meta)
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// Framework logging
|
|
86
|
-
framework(message: string, meta?: any): void {
|
|
87
|
-
this.info(`[FluxStack] ${message}`, meta)
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// Export singleton instance
|
|
92
|
-
export const logger = Logger.getInstance()
|
|
93
|
-
|
|
94
|
-
// Export convenience functions
|
|
95
|
-
export const log = {
|
|
96
|
-
debug: (message: string, meta?: any) => logger.debug(message, meta),
|
|
97
|
-
info: (message: string, meta?: any) => logger.info(message, meta),
|
|
98
|
-
warn: (message: string, meta?: any) => logger.warn(message, meta),
|
|
99
|
-
error: (message: string, meta?: any) => logger.error(message, meta),
|
|
100
|
-
request: (method: string, path: string, status?: number, duration?: number) =>
|
|
101
|
-
logger.request(method, path, status, duration),
|
|
102
|
-
plugin: (pluginName: string, message: string, meta?: any) =>
|
|
103
|
-
logger.plugin(pluginName, message, meta),
|
|
104
|
-
framework: (message: string, meta?: any) =>
|
|
105
|
-
logger.framework(message, meta)
|
|
106
|
-
}
|