@hamak/logging-impl 0.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.
Files changed (57) hide show
  1. package/dist/core/context-logger.d.ts +26 -0
  2. package/dist/core/context-logger.d.ts.map +1 -0
  3. package/dist/core/context-logger.js +82 -0
  4. package/dist/core/index.d.ts +3 -0
  5. package/dist/core/index.d.ts.map +1 -0
  6. package/dist/core/index.js +2 -0
  7. package/dist/core/log-manager.d.ts +41 -0
  8. package/dist/core/log-manager.d.ts.map +1 -0
  9. package/dist/core/log-manager.js +241 -0
  10. package/dist/es2015/core/context-logger.js +74 -0
  11. package/dist/es2015/core/index.js +2 -0
  12. package/dist/es2015/core/log-manager.js +255 -0
  13. package/dist/es2015/formatters/dev-formatter.js +152 -0
  14. package/dist/es2015/formatters/index.js +2 -0
  15. package/dist/es2015/formatters/json-formatter.js +69 -0
  16. package/dist/es2015/index.js +19 -0
  17. package/dist/es2015/plugin/index.js +1 -0
  18. package/dist/es2015/plugin/logging-plugin-factory.js +118 -0
  19. package/dist/es2015/transports/console-transport.js +41 -0
  20. package/dist/es2015/transports/index.js +1 -0
  21. package/dist/es2015/utils/console-interceptor.js +105 -0
  22. package/dist/es2015/utils/event-emitter.js +39 -0
  23. package/dist/es2015/utils/index.js +2 -0
  24. package/dist/formatters/dev-formatter.d.ts +20 -0
  25. package/dist/formatters/dev-formatter.d.ts.map +1 -0
  26. package/dist/formatters/dev-formatter.js +140 -0
  27. package/dist/formatters/index.d.ts +3 -0
  28. package/dist/formatters/index.d.ts.map +1 -0
  29. package/dist/formatters/index.js +2 -0
  30. package/dist/formatters/json-formatter.d.ts +24 -0
  31. package/dist/formatters/json-formatter.d.ts.map +1 -0
  32. package/dist/formatters/json-formatter.js +65 -0
  33. package/dist/index.d.ts +16 -0
  34. package/dist/index.d.ts.map +1 -0
  35. package/dist/index.js +19 -0
  36. package/dist/plugin/index.d.ts +2 -0
  37. package/dist/plugin/index.d.ts.map +1 -0
  38. package/dist/plugin/index.js +1 -0
  39. package/dist/plugin/logging-plugin-factory.d.ts +37 -0
  40. package/dist/plugin/logging-plugin-factory.d.ts.map +1 -0
  41. package/dist/plugin/logging-plugin-factory.js +112 -0
  42. package/dist/transports/console-transport.d.ts +16 -0
  43. package/dist/transports/console-transport.d.ts.map +1 -0
  44. package/dist/transports/console-transport.js +40 -0
  45. package/dist/transports/index.d.ts +2 -0
  46. package/dist/transports/index.d.ts.map +1 -0
  47. package/dist/transports/index.js +1 -0
  48. package/dist/utils/console-interceptor.d.ts +36 -0
  49. package/dist/utils/console-interceptor.d.ts.map +1 -0
  50. package/dist/utils/console-interceptor.js +105 -0
  51. package/dist/utils/event-emitter.d.ts +11 -0
  52. package/dist/utils/event-emitter.d.ts.map +1 -0
  53. package/dist/utils/event-emitter.js +39 -0
  54. package/dist/utils/index.d.ts +3 -0
  55. package/dist/utils/index.d.ts.map +1 -0
  56. package/dist/utils/index.js +2 -0
  57. package/package.json +54 -0
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Console interceptor that routes console methods through the logging system
3
+ *
4
+ * By default, this is enabled. Set `interceptConsole: false` in LoggingPluginConfig to disable.
5
+ */
6
+ export class ConsoleInterceptor {
7
+ constructor(logManager) {
8
+ this.logManager = logManager;
9
+ this.isIntercepting = false;
10
+ // Store original console methods
11
+ this.originalConsole = {
12
+ log: console.log.bind(console),
13
+ debug: console.debug.bind(console),
14
+ info: console.info.bind(console),
15
+ warn: console.warn.bind(console),
16
+ error: console.error.bind(console),
17
+ trace: console.trace.bind(console),
18
+ };
19
+ }
20
+ /**
21
+ * Start intercepting console methods
22
+ */
23
+ intercept() {
24
+ if (this.isIntercepting) {
25
+ return;
26
+ }
27
+ const logger = this.logManager.createLogger({
28
+ plugin: 'console-interceptor',
29
+ module: 'global'
30
+ });
31
+ // Intercept console.log
32
+ console.log = (...args) => {
33
+ logger.info(this.formatMessage(args));
34
+ };
35
+ // Intercept console.debug
36
+ console.debug = (...args) => {
37
+ logger.debug(this.formatMessage(args));
38
+ };
39
+ // Intercept console.info
40
+ console.info = (...args) => {
41
+ logger.info(this.formatMessage(args));
42
+ };
43
+ // Intercept console.warn
44
+ console.warn = (...args) => {
45
+ logger.warn(this.formatMessage(args));
46
+ };
47
+ // Intercept console.error
48
+ console.error = (...args) => {
49
+ const message = this.formatMessage(args);
50
+ const error = args.find(arg => arg instanceof Error);
51
+ logger.error(message, error);
52
+ };
53
+ // Intercept console.trace
54
+ console.trace = (...args) => {
55
+ const message = this.formatMessage(args);
56
+ logger.debug(message, {
57
+ stack: new Error().stack,
58
+ tags: ['trace']
59
+ });
60
+ };
61
+ this.isIntercepting = true;
62
+ }
63
+ /**
64
+ * Stop intercepting and restore original console methods
65
+ */
66
+ restore() {
67
+ if (!this.isIntercepting) {
68
+ return;
69
+ }
70
+ console.log = this.originalConsole.log;
71
+ console.debug = this.originalConsole.debug;
72
+ console.info = this.originalConsole.info;
73
+ console.warn = this.originalConsole.warn;
74
+ console.error = this.originalConsole.error;
75
+ console.trace = this.originalConsole.trace;
76
+ this.isIntercepting = false;
77
+ }
78
+ /**
79
+ * Get original console for direct access
80
+ */
81
+ getOriginalConsole() {
82
+ return this.originalConsole;
83
+ }
84
+ /**
85
+ * Format console arguments into a single message
86
+ */
87
+ formatMessage(args) {
88
+ return args
89
+ .map(arg => {
90
+ if (typeof arg === 'string') {
91
+ return arg;
92
+ }
93
+ if (arg instanceof Error) {
94
+ return `${arg.name}: ${arg.message}`;
95
+ }
96
+ try {
97
+ return JSON.stringify(arg);
98
+ }
99
+ catch (_a) {
100
+ return String(arg);
101
+ }
102
+ })
103
+ .join(' ');
104
+ }
105
+ }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Simple event emitter for internal use
3
+ */
4
+ export class EventEmitter {
5
+ constructor() {
6
+ this.listeners = new Map();
7
+ }
8
+ on(event, handler) {
9
+ if (!this.listeners.has(event)) {
10
+ this.listeners.set(event, new Set());
11
+ }
12
+ this.listeners.get(event).add(handler);
13
+ }
14
+ off(event, handler) {
15
+ const handlers = this.listeners.get(event);
16
+ if (handlers) {
17
+ handlers.delete(handler);
18
+ if (handlers.size === 0) {
19
+ this.listeners.delete(event);
20
+ }
21
+ }
22
+ }
23
+ emit(event, ...args) {
24
+ const handlers = this.listeners.get(event);
25
+ if (handlers) {
26
+ handlers.forEach(handler => {
27
+ try {
28
+ handler(...args);
29
+ }
30
+ catch (error) {
31
+ console.error(`[EventEmitter] Error in handler for '${event}':`, error);
32
+ }
33
+ });
34
+ }
35
+ }
36
+ clear() {
37
+ this.listeners.clear();
38
+ }
39
+ }
@@ -0,0 +1,2 @@
1
+ export * from './event-emitter.js';
2
+ export * from './console-interceptor.js';
@@ -0,0 +1,20 @@
1
+ import type { ILogFormatter, LogEntry, ConsoleTransportConfig } from '@hamak/logging-api';
2
+ /**
3
+ * Development formatter with colors and emojis
4
+ *
5
+ * Provides rich, human-readable console output for development.
6
+ */
7
+ export declare class DevFormatter implements ILogFormatter {
8
+ private config;
9
+ constructor(config?: ConsoleTransportConfig);
10
+ format(entry: LogEntry): string;
11
+ formatBatch(entries: LogEntry[]): string;
12
+ private formatTimestamp;
13
+ private formatLevel;
14
+ private getLevelEmoji;
15
+ private getLevelLabel;
16
+ private colorize;
17
+ private formatContext;
18
+ private formatMetadata;
19
+ }
20
+ //# sourceMappingURL=dev-formatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev-formatter.d.ts","sourceRoot":"","sources":["../../src/formatters/dev-formatter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAqC,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAE7H;;;;GAIG;AACH,qBAAa,YAAa,YAAW,aAAa;IACpC,OAAO,CAAC,MAAM;gBAAN,MAAM,GAAE,sBAA2B;IASvD,MAAM,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM;IA+B/B,WAAW,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM;IAIxC,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,QAAQ;IAehB,OAAO,CAAC,aAAa;IAkCrB,OAAO,CAAC,cAAc;CAiCvB"}
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Development formatter with colors and emojis
3
+ *
4
+ * Provides rich, human-readable console output for development.
5
+ */
6
+ export class DevFormatter {
7
+ constructor(config = {}) {
8
+ this.config = config;
9
+ this.config = {
10
+ colors: config.colors ?? true,
11
+ emojis: config.emojis ?? true,
12
+ timestamps: config.timestamps ?? true,
13
+ showContext: config.showContext ?? true,
14
+ };
15
+ }
16
+ format(entry) {
17
+ const parts = [];
18
+ // Timestamp
19
+ if (this.config.timestamps) {
20
+ parts.push(this.formatTimestamp(entry.timestamp));
21
+ }
22
+ // Level with emoji and color
23
+ parts.push(this.formatLevel(entry.level));
24
+ // Context (plugin/module/component)
25
+ if (this.config.showContext) {
26
+ const context = this.formatContext(entry.context);
27
+ if (context) {
28
+ parts.push(context);
29
+ }
30
+ }
31
+ // Message
32
+ parts.push(entry.message);
33
+ // Metadata
34
+ const metadata = this.formatMetadata(entry.metadata);
35
+ if (metadata) {
36
+ parts.push(metadata);
37
+ }
38
+ return parts.join(' ');
39
+ }
40
+ formatBatch(entries) {
41
+ return entries.map(e => this.format(e)).join('\n');
42
+ }
43
+ formatTimestamp(timestamp) {
44
+ const date = new Date(timestamp);
45
+ const time = date.toISOString().split('T')[1].split('.')[0];
46
+ return this.config.colors ? `\x1b[90m${time}\x1b[0m` : time;
47
+ }
48
+ formatLevel(level) {
49
+ const emoji = this.config.emojis ? this.getLevelEmoji(level) : '';
50
+ const label = this.getLevelLabel(level);
51
+ const colored = this.config.colors ? this.colorize(label, level) : label;
52
+ return emoji ? `${emoji} ${colored}` : colored;
53
+ }
54
+ getLevelEmoji(level) {
55
+ switch (level) {
56
+ case 0: return '🔍'; // TRACE
57
+ case 1: return '🐛'; // DEBUG
58
+ case 2: return 'ℹ️ '; // INFO
59
+ case 3: return '⚠️ '; // WARN
60
+ case 4: return '❌'; // ERROR
61
+ case 5: return '💀'; // FATAL
62
+ default: return '';
63
+ }
64
+ }
65
+ getLevelLabel(level) {
66
+ switch (level) {
67
+ case 0: return 'TRACE';
68
+ case 1: return 'DEBUG';
69
+ case 2: return 'INFO ';
70
+ case 3: return 'WARN ';
71
+ case 4: return 'ERROR';
72
+ case 5: return 'FATAL';
73
+ default: return 'UNKNW';
74
+ }
75
+ }
76
+ colorize(text, level) {
77
+ const colors = {
78
+ 0: '\x1b[90m', // TRACE - Gray
79
+ 1: '\x1b[36m', // DEBUG - Cyan
80
+ 2: '\x1b[32m', // INFO - Green
81
+ 3: '\x1b[33m', // WARN - Yellow
82
+ 4: '\x1b[31m', // ERROR - Red
83
+ 5: '\x1b[35m', // FATAL - Magenta
84
+ };
85
+ const color = colors[level] || '\x1b[0m';
86
+ const reset = '\x1b[0m';
87
+ return `${color}${text}${reset}`;
88
+ }
89
+ formatContext(context) {
90
+ const parts = [];
91
+ if (context.plugin) {
92
+ parts.push(this.config.colors
93
+ ? `\x1b[35m[${context.plugin}]\x1b[0m`
94
+ : `[${context.plugin}]`);
95
+ }
96
+ if (context.module) {
97
+ parts.push(this.config.colors
98
+ ? `\x1b[34m{${context.module}}\x1b[0m`
99
+ : `{${context.module}}`);
100
+ }
101
+ if (context.component) {
102
+ parts.push(this.config.colors
103
+ ? `\x1b[36m<${context.component}>\x1b[0m`
104
+ : `<${context.component}>`);
105
+ }
106
+ if (context.operation) {
107
+ parts.push(this.config.colors
108
+ ? `\x1b[90m(${context.operation})\x1b[0m`
109
+ : `(${context.operation})`);
110
+ }
111
+ return parts.join(' ');
112
+ }
113
+ formatMetadata(metadata) {
114
+ if (!metadata || Object.keys(metadata).length === 0) {
115
+ return '';
116
+ }
117
+ const { error, stack, tags, duration, ...rest } = metadata;
118
+ const parts = [];
119
+ // Duration
120
+ if (duration !== undefined) {
121
+ const color = this.config.colors ? '\x1b[33m' : '';
122
+ const reset = this.config.colors ? '\x1b[0m' : '';
123
+ parts.push(`${color}⏱ ${duration}ms${reset}`);
124
+ }
125
+ // Tags
126
+ if (tags && tags.length > 0) {
127
+ const tagString = tags.map(t => `#${t}`).join(' ');
128
+ const color = this.config.colors ? '\x1b[90m' : '';
129
+ const reset = this.config.colors ? '\x1b[0m' : '';
130
+ parts.push(`${color}${tagString}${reset}`);
131
+ }
132
+ // Other metadata
133
+ if (Object.keys(rest).length > 0) {
134
+ const color = this.config.colors ? '\x1b[90m' : '';
135
+ const reset = this.config.colors ? '\x1b[0m' : '';
136
+ parts.push(`${color}${JSON.stringify(rest)}${reset}`);
137
+ }
138
+ return parts.length > 0 ? parts.join(' ') : '';
139
+ }
140
+ }
@@ -0,0 +1,3 @@
1
+ export * from './dev-formatter.js';
2
+ export * from './json-formatter.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/formatters/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './dev-formatter.js';
2
+ export * from './json-formatter.js';
@@ -0,0 +1,24 @@
1
+ import type { ILogFormatter, LogEntry } from '@hamak/logging-api';
2
+ /**
3
+ * JSON formatter for structured logging
4
+ *
5
+ * Outputs logs as JSON for easy parsing by log aggregation tools.
6
+ */
7
+ export declare class JsonFormatter implements ILogFormatter {
8
+ private config;
9
+ constructor(config?: JsonFormatterConfig);
10
+ format(entry: LogEntry): string;
11
+ formatBatch(entries: LogEntry[]): string;
12
+ private toObject;
13
+ private getLevelName;
14
+ }
15
+ /**
16
+ * Configuration for JSON formatter
17
+ */
18
+ export interface JsonFormatterConfig {
19
+ /** Pretty print JSON (with indentation) */
20
+ pretty?: boolean;
21
+ /** Include stack traces for errors */
22
+ includeStack?: boolean;
23
+ }
24
+ //# sourceMappingURL=json-formatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-formatter.d.ts","sourceRoot":"","sources":["../../src/formatters/json-formatter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAElE;;;;GAIG;AACH,qBAAa,aAAc,YAAW,aAAa;IACrC,OAAO,CAAC,MAAM;gBAAN,MAAM,GAAE,mBAAwB;IAQpD,MAAM,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM;IAO/B,WAAW,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM;IAOxC,OAAO,CAAC,QAAQ;IAiChB,OAAO,CAAC,YAAY;CAWrB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,2CAA2C;IAC3C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,sCAAsC;IACtC,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * JSON formatter for structured logging
3
+ *
4
+ * Outputs logs as JSON for easy parsing by log aggregation tools.
5
+ */
6
+ export class JsonFormatter {
7
+ constructor(config = {}) {
8
+ this.config = config;
9
+ this.config = {
10
+ pretty: config.pretty ?? false,
11
+ includeStack: config.includeStack ?? true,
12
+ ...config,
13
+ };
14
+ }
15
+ format(entry) {
16
+ const logObject = this.toObject(entry);
17
+ return this.config.pretty
18
+ ? JSON.stringify(logObject, null, 2)
19
+ : JSON.stringify(logObject);
20
+ }
21
+ formatBatch(entries) {
22
+ const logObjects = entries.map(e => this.toObject(e));
23
+ return this.config.pretty
24
+ ? JSON.stringify(logObjects, null, 2)
25
+ : JSON.stringify(logObjects);
26
+ }
27
+ toObject(entry) {
28
+ const obj = {
29
+ timestamp: entry.timestamp,
30
+ level: this.getLevelName(entry.level),
31
+ message: entry.message,
32
+ };
33
+ // Add context
34
+ if (entry.context && Object.keys(entry.context).length > 0) {
35
+ obj.context = entry.context;
36
+ }
37
+ // Add metadata
38
+ if (entry.metadata) {
39
+ const { error, stack, ...rest } = entry.metadata;
40
+ if (Object.keys(rest).length > 0) {
41
+ obj.metadata = rest;
42
+ }
43
+ // Handle error separately
44
+ if (error) {
45
+ obj.error = {
46
+ name: error.name,
47
+ message: error.message,
48
+ ...(this.config.includeStack && stack ? { stack } : {}),
49
+ };
50
+ }
51
+ }
52
+ return obj;
53
+ }
54
+ getLevelName(level) {
55
+ switch (level) {
56
+ case 0: return 'TRACE';
57
+ case 1: return 'DEBUG';
58
+ case 2: return 'INFO';
59
+ case 3: return 'WARN';
60
+ case 4: return 'ERROR';
61
+ case 5: return 'FATAL';
62
+ default: return 'UNKNOWN';
63
+ }
64
+ }
65
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @hamak/logging-impl
3
+ *
4
+ * Core implementation of the pluggable logging system.
5
+ * Provides LogManager, ContextLogger, transports, and formatters.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ export * from './core/index.js';
10
+ export * from './transports/index.js';
11
+ export * from './formatters/index.js';
12
+ export * from './plugin/index.js';
13
+ export * from './utils/index.js';
14
+ export type { ILogger, ILogTransport, ILogFormatter, ILogManager, LogLevel, LogEntry, LogContext, LogMetadata, TransportConfig, LogManagerConfig, ConsoleTransportConfig, RemoteTransportConfig, } from '@hamak/logging-api';
15
+ export { LOG_MANAGER_TOKEN, LOGGER_TOKEN, LOG_CONFIG_TOKEN, } from '@hamak/logging-api';
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,cAAc,iBAAiB,CAAC;AAGhC,cAAc,uBAAuB,CAAC;AAGtC,cAAc,uBAAuB,CAAC;AAGtC,cAAc,mBAAmB,CAAC;AAGlC,cAAc,kBAAkB,CAAC;AAGjC,YAAY,EACV,OAAO,EACP,aAAa,EACb,aAAa,EACb,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,WAAW,EACX,eAAe,EACf,gBAAgB,EAChB,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,gBAAgB,GACjB,MAAM,oBAAoB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,19 @@
1
+ /**
2
+ * @hamak/logging-impl
3
+ *
4
+ * Core implementation of the pluggable logging system.
5
+ * Provides LogManager, ContextLogger, transports, and formatters.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ // Export core implementations
10
+ export * from './core/index.js';
11
+ // Export transports
12
+ export * from './transports/index.js';
13
+ // Export formatters
14
+ export * from './formatters/index.js';
15
+ // Export plugin factory
16
+ export * from './plugin/index.js';
17
+ // Export utilities
18
+ export * from './utils/index.js';
19
+ export { LOG_MANAGER_TOKEN, LOGGER_TOKEN, LOG_CONFIG_TOKEN, } from '@hamak/logging-api';
@@ -0,0 +1,2 @@
1
+ export * from './logging-plugin-factory.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugin/index.ts"],"names":[],"mappings":"AAAA,cAAc,6BAA6B,CAAC"}
@@ -0,0 +1 @@
1
+ export * from './logging-plugin-factory.js';
@@ -0,0 +1,37 @@
1
+ import type { PluginModule } from '@hamak/microkernel-spi';
2
+ import type { LogManagerConfig } from '@hamak/logging-api';
3
+ /**
4
+ * Configuration for the logging plugin
5
+ */
6
+ export interface LoggingPluginConfig extends LogManagerConfig {
7
+ /** Use development formatter (rich console output) */
8
+ devFormatter?: boolean;
9
+ /** Remote transport configuration */
10
+ remoteTransport?: any;
11
+ /**
12
+ * Intercept console.log/warn/error and route through logging system
13
+ * @default true - Enabled by default, set to false to disable
14
+ */
15
+ interceptConsole?: boolean;
16
+ }
17
+ /**
18
+ * Create a logging plugin for the microkernel
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * import { createLoggingPlugin } from '@hamak/logging-impl';
23
+ *
24
+ * const loggingPlugin = createLoggingPlugin({
25
+ * globalLevel: LogLevel.DEBUG,
26
+ * pluginLevels: {
27
+ * 'my-plugin': LogLevel.TRACE
28
+ * }
29
+ * });
30
+ *
31
+ * const host = createHost({
32
+ * plugins: [loggingPlugin, myPlugin]
33
+ * });
34
+ * ```
35
+ */
36
+ export declare function createLoggingPlugin(config?: LoggingPluginConfig): PluginModule;
37
+ //# sourceMappingURL=logging-plugin-factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logging-plugin-factory.d.ts","sourceRoot":"","sources":["../../src/plugin/logging-plugin-factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAyB,MAAM,wBAAwB,CAAC;AAElF,OAAO,KAAK,EAAW,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAQpE;;GAEG;AACH,MAAM,WAAW,mBAAoB,SAAQ,gBAAgB;IAC3D,sDAAsD;IACtD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,qCAAqC;IACrC,eAAe,CAAC,EAAE,GAAG,CAAC;IACtB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,GAAE,mBAAwB,GAAG,YAAY,CAyGlF"}
@@ -0,0 +1,112 @@
1
+ import { LOG_MANAGER_TOKEN, LOGGER_TOKEN, LOG_CONFIG_TOKEN } from '@hamak/logging-api';
2
+ import { LogManager } from '../core/log-manager.js';
3
+ import { ConsoleTransport } from '../transports/console-transport.js';
4
+ import { DevFormatter } from '../formatters/dev-formatter.js';
5
+ import { JsonFormatter } from '../formatters/json-formatter.js';
6
+ import { ConsoleInterceptor } from '../utils/console-interceptor.js';
7
+ /**
8
+ * Create a logging plugin for the microkernel
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import { createLoggingPlugin } from '@hamak/logging-impl';
13
+ *
14
+ * const loggingPlugin = createLoggingPlugin({
15
+ * globalLevel: LogLevel.DEBUG,
16
+ * pluginLevels: {
17
+ * 'my-plugin': LogLevel.TRACE
18
+ * }
19
+ * });
20
+ *
21
+ * const host = createHost({
22
+ * plugins: [loggingPlugin, myPlugin]
23
+ * });
24
+ * ```
25
+ */
26
+ export function createLoggingPlugin(config = {}) {
27
+ let logManager;
28
+ let rootLogger;
29
+ let consoleInterceptor;
30
+ // Determine environment
31
+ const isDevelopment = typeof process !== 'undefined'
32
+ ? process.env.NODE_ENV === 'development'
33
+ : true;
34
+ const defaultConfig = {
35
+ globalLevel: isDevelopment ? 1 : 2, // DEBUG in dev, INFO in prod
36
+ bufferSize: 1000,
37
+ flushInterval: 5000,
38
+ devFormatter: isDevelopment,
39
+ interceptConsole: true, // Enabled by default
40
+ pluginLevels: {},
41
+ moduleLevels: {},
42
+ ...config,
43
+ };
44
+ return {
45
+ async initialize(ctx) {
46
+ // Create log manager
47
+ logManager = new LogManager(defaultConfig);
48
+ rootLogger = logManager.createLogger({ plugin: 'logging', module: 'plugin' });
49
+ // Register console transport
50
+ const formatter = defaultConfig.devFormatter
51
+ ? new DevFormatter({
52
+ colors: true,
53
+ emojis: true,
54
+ timestamps: true,
55
+ showContext: true,
56
+ })
57
+ : new JsonFormatter({ pretty: isDevelopment });
58
+ logManager.registerTransport(new ConsoleTransport(formatter), {
59
+ id: 'console',
60
+ enabled: true,
61
+ minLevel: defaultConfig.globalLevel,
62
+ });
63
+ // Register services via DI
64
+ ctx.provide({ provide: LOG_MANAGER_TOKEN, useValue: logManager });
65
+ ctx.provide({ provide: LOG_CONFIG_TOKEN, useValue: defaultConfig });
66
+ // Provide logger factory
67
+ ctx.provide({
68
+ provide: LOGGER_TOKEN,
69
+ useFactory: (pluginName) => {
70
+ return logManager.createLogger({ plugin: pluginName });
71
+ },
72
+ deps: [],
73
+ });
74
+ rootLogger.info('Logging plugin initialized', {
75
+ globalLevel: defaultConfig.globalLevel,
76
+ formatter: defaultConfig.devFormatter ? 'dev' : 'json',
77
+ tags: ['initialization'],
78
+ });
79
+ },
80
+ async activate(ctx) {
81
+ // Bridge microkernel events to logging
82
+ ctx.hooks.on('plugin:error', ({ plugin, error }) => {
83
+ const logger = logManager.createLogger({ plugin });
84
+ logger.error('Plugin error', error);
85
+ });
86
+ ctx.hooks.on('host:activated', () => {
87
+ rootLogger.info('Microkernel host activated', { tags: ['lifecycle'] });
88
+ });
89
+ // Intercept console methods if enabled
90
+ if (defaultConfig.interceptConsole) {
91
+ consoleInterceptor = new ConsoleInterceptor(logManager);
92
+ consoleInterceptor.intercept();
93
+ rootLogger.debug('Console interception enabled', { tags: ['console'] });
94
+ }
95
+ // Emit logging ready event
96
+ ctx.hooks.emit('logging:ready', { logManager });
97
+ rootLogger.info('Logging plugin activated', {
98
+ tags: ['lifecycle'],
99
+ interceptConsole: defaultConfig.interceptConsole,
100
+ });
101
+ },
102
+ async deactivate() {
103
+ rootLogger.info('Logging plugin deactivating', { tags: ['lifecycle'] });
104
+ // Restore original console methods
105
+ if (consoleInterceptor) {
106
+ consoleInterceptor.restore();
107
+ rootLogger.debug('Console interception disabled', { tags: ['console'] });
108
+ }
109
+ await logManager.destroy();
110
+ },
111
+ };
112
+ }
@@ -0,0 +1,16 @@
1
+ import type { ILogTransport, ILogFormatter, LogEntry } from '@hamak/logging-api';
2
+ /**
3
+ * Console transport
4
+ *
5
+ * Outputs logs to the browser console or Node.js console.
6
+ * Supports formatting via pluggable formatters.
7
+ */
8
+ export declare class ConsoleTransport implements ILogTransport {
9
+ private formatter;
10
+ readonly id = "console";
11
+ readonly name = "Console Transport";
12
+ constructor(formatter: ILogFormatter);
13
+ log(entry: LogEntry): void;
14
+ onError(error: Error): void;
15
+ }
16
+ //# sourceMappingURL=console-transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"console-transport.d.ts","sourceRoot":"","sources":["../../src/transports/console-transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEjF;;;;;GAKG;AACH,qBAAa,gBAAiB,YAAW,aAAa;IAIxC,OAAO,CAAC,SAAS;IAH7B,QAAQ,CAAC,EAAE,aAAa;IACxB,QAAQ,CAAC,IAAI,uBAAuB;gBAEhB,SAAS,EAAE,aAAa;IAE5C,GAAG,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;IA8B1B,OAAO,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;CAG5B"}