@xrystal/core 3.5.6 → 3.5.7
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/package.json +1 -1
- package/source/loader/logger/index.js +53 -46
- package/x/dist/loader/logger/index.js +53 -46
package/package.json
CHANGED
|
@@ -1,9 +1,26 @@
|
|
|
1
1
|
import winston, { format } from "winston";
|
|
2
|
+
import Transport from "winston-transport";
|
|
2
3
|
import "winston-daily-rotate-file";
|
|
3
4
|
import path from "node:path";
|
|
4
5
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
5
6
|
import { Kafka, Partitioners, logLevel } from "kafkajs";
|
|
6
7
|
import { LoggerLayerEnum } from "../../utils";
|
|
8
|
+
class KafkaTransport extends Transport {
|
|
9
|
+
service;
|
|
10
|
+
constructor(opts, service) {
|
|
11
|
+
super(opts);
|
|
12
|
+
this.service = service;
|
|
13
|
+
}
|
|
14
|
+
log(info, callback) {
|
|
15
|
+
setImmediate(() => {
|
|
16
|
+
this.emit("logged", info);
|
|
17
|
+
});
|
|
18
|
+
if (this.service["isKafkaReady"]) {
|
|
19
|
+
this.service["logToKafka"](info);
|
|
20
|
+
}
|
|
21
|
+
callback();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
7
24
|
const customLevels = {
|
|
8
25
|
critical: LoggerLayerEnum.CRITICAL,
|
|
9
26
|
error: LoggerLayerEnum.ERROR,
|
|
@@ -38,11 +55,6 @@ export default class LoggerService {
|
|
|
38
55
|
if (store) {
|
|
39
56
|
info.id = store.get("correlationId");
|
|
40
57
|
}
|
|
41
|
-
Object.keys(info).forEach(key => {
|
|
42
|
-
if (info[key] instanceof Headers) {
|
|
43
|
-
info[key] = Object.fromEntries(info[key].entries());
|
|
44
|
-
}
|
|
45
|
-
});
|
|
46
58
|
return info;
|
|
47
59
|
});
|
|
48
60
|
getConsoleFormat() {
|
|
@@ -75,10 +87,6 @@ export default class LoggerService {
|
|
|
75
87
|
this.serviceName = config?.serviceName || "service";
|
|
76
88
|
this.environment = config?.env || "dev";
|
|
77
89
|
this.kafkaTopic = config?.kafkaTopic || "logs";
|
|
78
|
-
this.winstonLoader({
|
|
79
|
-
loadPath: config?.loadPath || "./logs",
|
|
80
|
-
loggerLevel: config?.loggerLevel || "debug"
|
|
81
|
-
});
|
|
82
90
|
const rawBrokers = config?.kafkaBrokers;
|
|
83
91
|
const brokers = rawBrokers ? String(rawBrokers).split(",").map((b) => b.trim()) : [];
|
|
84
92
|
if (brokers.length > 0) {
|
|
@@ -86,57 +94,56 @@ export default class LoggerService {
|
|
|
86
94
|
clientId: this.serviceName,
|
|
87
95
|
brokers: brokers,
|
|
88
96
|
logLevel: logLevel.ERROR,
|
|
89
|
-
retry: {
|
|
90
|
-
initialRetryTime: 1000,
|
|
91
|
-
retries: 10,
|
|
92
|
-
maxRetryTime: 30000,
|
|
93
|
-
factor: 2
|
|
94
|
-
},
|
|
95
97
|
});
|
|
96
|
-
this.kafkaProducer = kafka.producer({
|
|
97
|
-
|
|
98
|
+
this.kafkaProducer = kafka.producer({
|
|
99
|
+
createPartitioner: Partitioners.DefaultPartitioner
|
|
100
|
+
});
|
|
101
|
+
const connect = async () => {
|
|
98
102
|
try {
|
|
99
103
|
await this.kafkaProducer?.connect();
|
|
100
104
|
this.isKafkaReady = true;
|
|
101
105
|
}
|
|
102
106
|
catch (err) {
|
|
103
107
|
this.isKafkaReady = false;
|
|
104
|
-
setTimeout(
|
|
108
|
+
setTimeout(connect, 5000);
|
|
105
109
|
}
|
|
106
110
|
};
|
|
107
|
-
|
|
111
|
+
await connect();
|
|
108
112
|
}
|
|
113
|
+
this.winstonLoader({
|
|
114
|
+
loadPath: config?.loadPath || "./logs",
|
|
115
|
+
loggerLevel: config?.loggerLevel || "debug"
|
|
116
|
+
});
|
|
109
117
|
};
|
|
110
118
|
winstonLoader = ({ loadPath, loggerLevel }) => {
|
|
111
119
|
const { combine, timestamp, json, errors } = format;
|
|
112
120
|
const jsonFileFormat = combine(this.getTracingFormat(), timestamp({ format: "YYYY-MM-DD HH:mm:ss" }), errors({ stack: true }), json({ replacer: this.safeReplacer }));
|
|
121
|
+
const transports = [
|
|
122
|
+
new winston.transports.Console({
|
|
123
|
+
format: this.getConsoleFormat()
|
|
124
|
+
}),
|
|
125
|
+
new winston.transports.DailyRotateFile({
|
|
126
|
+
filename: path.resolve(loadPath, "error", "%DATE%_error.log"),
|
|
127
|
+
level: "error",
|
|
128
|
+
format: jsonFileFormat,
|
|
129
|
+
maxSize: "2mb",
|
|
130
|
+
maxFiles: "7d"
|
|
131
|
+
}),
|
|
132
|
+
new winston.transports.DailyRotateFile({
|
|
133
|
+
filename: path.resolve(loadPath, "critical", "%DATE%_critical.log"),
|
|
134
|
+
level: "critical",
|
|
135
|
+
format: jsonFileFormat,
|
|
136
|
+
maxSize: "2mb",
|
|
137
|
+
maxFiles: "14d"
|
|
138
|
+
})
|
|
139
|
+
];
|
|
140
|
+
if (this.kafkaProducer) {
|
|
141
|
+
transports.push(new KafkaTransport({ level: loggerLevel }, this));
|
|
142
|
+
}
|
|
113
143
|
const winstonLogger = winston.createLogger({
|
|
114
144
|
level: loggerLevel,
|
|
115
145
|
levels: customLevels,
|
|
116
|
-
transports
|
|
117
|
-
new winston.transports.Console({
|
|
118
|
-
format: this.getConsoleFormat()
|
|
119
|
-
}),
|
|
120
|
-
new winston.transports.DailyRotateFile({
|
|
121
|
-
filename: path.resolve(loadPath, "error", "%DATE%_error.log"),
|
|
122
|
-
level: "error",
|
|
123
|
-
format: jsonFileFormat,
|
|
124
|
-
maxSize: "2mb",
|
|
125
|
-
maxFiles: "7d"
|
|
126
|
-
}),
|
|
127
|
-
new winston.transports.DailyRotateFile({
|
|
128
|
-
filename: path.resolve(loadPath, "critical", "%DATE%_critical.log"),
|
|
129
|
-
level: "critical",
|
|
130
|
-
format: jsonFileFormat,
|
|
131
|
-
maxSize: "2mb",
|
|
132
|
-
maxFiles: "14d"
|
|
133
|
-
})
|
|
134
|
-
]
|
|
135
|
-
});
|
|
136
|
-
winstonLogger.on("data", (info) => {
|
|
137
|
-
if (this.isKafkaReady) {
|
|
138
|
-
this.logToKafka(info);
|
|
139
|
-
}
|
|
146
|
+
transports
|
|
140
147
|
});
|
|
141
148
|
this.winston = winstonLogger;
|
|
142
149
|
return winstonLogger;
|
|
@@ -150,13 +157,13 @@ export default class LoggerService {
|
|
|
150
157
|
topic: this.kafkaTopic,
|
|
151
158
|
messages: [{
|
|
152
159
|
value: JSON.stringify({
|
|
153
|
-
|
|
160
|
+
id: id || null,
|
|
154
161
|
service: this.serviceName,
|
|
162
|
+
env: this.environment,
|
|
155
163
|
level,
|
|
156
164
|
message,
|
|
157
165
|
...rest,
|
|
158
|
-
|
|
159
|
-
env: this.environment,
|
|
166
|
+
timestamp: new Date().toISOString()
|
|
160
167
|
}, this.safeReplacer)
|
|
161
168
|
}]
|
|
162
169
|
});
|
|
@@ -1,9 +1,26 @@
|
|
|
1
1
|
import winston, { format } from "winston";
|
|
2
|
+
import Transport from "winston-transport";
|
|
2
3
|
import "winston-daily-rotate-file";
|
|
3
4
|
import path from "node:path";
|
|
4
5
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
5
6
|
import { Kafka, Partitioners, logLevel } from "kafkajs";
|
|
6
7
|
import { LoggerLayerEnum } from "../../utils";
|
|
8
|
+
class KafkaTransport extends Transport {
|
|
9
|
+
service;
|
|
10
|
+
constructor(opts, service) {
|
|
11
|
+
super(opts);
|
|
12
|
+
this.service = service;
|
|
13
|
+
}
|
|
14
|
+
log(info, callback) {
|
|
15
|
+
setImmediate(() => {
|
|
16
|
+
this.emit("logged", info);
|
|
17
|
+
});
|
|
18
|
+
if (this.service["isKafkaReady"]) {
|
|
19
|
+
this.service["logToKafka"](info);
|
|
20
|
+
}
|
|
21
|
+
callback();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
7
24
|
const customLevels = {
|
|
8
25
|
critical: LoggerLayerEnum.CRITICAL,
|
|
9
26
|
error: LoggerLayerEnum.ERROR,
|
|
@@ -38,11 +55,6 @@ export default class LoggerService {
|
|
|
38
55
|
if (store) {
|
|
39
56
|
info.id = store.get("correlationId");
|
|
40
57
|
}
|
|
41
|
-
Object.keys(info).forEach(key => {
|
|
42
|
-
if (info[key] instanceof Headers) {
|
|
43
|
-
info[key] = Object.fromEntries(info[key].entries());
|
|
44
|
-
}
|
|
45
|
-
});
|
|
46
58
|
return info;
|
|
47
59
|
});
|
|
48
60
|
getConsoleFormat() {
|
|
@@ -75,10 +87,6 @@ export default class LoggerService {
|
|
|
75
87
|
this.serviceName = config?.serviceName || "service";
|
|
76
88
|
this.environment = config?.env || "dev";
|
|
77
89
|
this.kafkaTopic = config?.kafkaTopic || "logs";
|
|
78
|
-
this.winstonLoader({
|
|
79
|
-
loadPath: config?.loadPath || "./logs",
|
|
80
|
-
loggerLevel: config?.loggerLevel || "debug"
|
|
81
|
-
});
|
|
82
90
|
const rawBrokers = config?.kafkaBrokers;
|
|
83
91
|
const brokers = rawBrokers ? String(rawBrokers).split(",").map((b) => b.trim()) : [];
|
|
84
92
|
if (brokers.length > 0) {
|
|
@@ -86,57 +94,56 @@ export default class LoggerService {
|
|
|
86
94
|
clientId: this.serviceName,
|
|
87
95
|
brokers: brokers,
|
|
88
96
|
logLevel: logLevel.ERROR,
|
|
89
|
-
retry: {
|
|
90
|
-
initialRetryTime: 1000,
|
|
91
|
-
retries: 10,
|
|
92
|
-
maxRetryTime: 30000,
|
|
93
|
-
factor: 2
|
|
94
|
-
},
|
|
95
97
|
});
|
|
96
|
-
this.kafkaProducer = kafka.producer({
|
|
97
|
-
|
|
98
|
+
this.kafkaProducer = kafka.producer({
|
|
99
|
+
createPartitioner: Partitioners.DefaultPartitioner
|
|
100
|
+
});
|
|
101
|
+
const connect = async () => {
|
|
98
102
|
try {
|
|
99
103
|
await this.kafkaProducer?.connect();
|
|
100
104
|
this.isKafkaReady = true;
|
|
101
105
|
}
|
|
102
106
|
catch (err) {
|
|
103
107
|
this.isKafkaReady = false;
|
|
104
|
-
setTimeout(
|
|
108
|
+
setTimeout(connect, 5000);
|
|
105
109
|
}
|
|
106
110
|
};
|
|
107
|
-
|
|
111
|
+
await connect();
|
|
108
112
|
}
|
|
113
|
+
this.winstonLoader({
|
|
114
|
+
loadPath: config?.loadPath || "./logs",
|
|
115
|
+
loggerLevel: config?.loggerLevel || "debug"
|
|
116
|
+
});
|
|
109
117
|
};
|
|
110
118
|
winstonLoader = ({ loadPath, loggerLevel }) => {
|
|
111
119
|
const { combine, timestamp, json, errors } = format;
|
|
112
120
|
const jsonFileFormat = combine(this.getTracingFormat(), timestamp({ format: "YYYY-MM-DD HH:mm:ss" }), errors({ stack: true }), json({ replacer: this.safeReplacer }));
|
|
121
|
+
const transports = [
|
|
122
|
+
new winston.transports.Console({
|
|
123
|
+
format: this.getConsoleFormat()
|
|
124
|
+
}),
|
|
125
|
+
new winston.transports.DailyRotateFile({
|
|
126
|
+
filename: path.resolve(loadPath, "error", "%DATE%_error.log"),
|
|
127
|
+
level: "error",
|
|
128
|
+
format: jsonFileFormat,
|
|
129
|
+
maxSize: "2mb",
|
|
130
|
+
maxFiles: "7d"
|
|
131
|
+
}),
|
|
132
|
+
new winston.transports.DailyRotateFile({
|
|
133
|
+
filename: path.resolve(loadPath, "critical", "%DATE%_critical.log"),
|
|
134
|
+
level: "critical",
|
|
135
|
+
format: jsonFileFormat,
|
|
136
|
+
maxSize: "2mb",
|
|
137
|
+
maxFiles: "14d"
|
|
138
|
+
})
|
|
139
|
+
];
|
|
140
|
+
if (this.kafkaProducer) {
|
|
141
|
+
transports.push(new KafkaTransport({ level: loggerLevel }, this));
|
|
142
|
+
}
|
|
113
143
|
const winstonLogger = winston.createLogger({
|
|
114
144
|
level: loggerLevel,
|
|
115
145
|
levels: customLevels,
|
|
116
|
-
transports
|
|
117
|
-
new winston.transports.Console({
|
|
118
|
-
format: this.getConsoleFormat()
|
|
119
|
-
}),
|
|
120
|
-
new winston.transports.DailyRotateFile({
|
|
121
|
-
filename: path.resolve(loadPath, "error", "%DATE%_error.log"),
|
|
122
|
-
level: "error",
|
|
123
|
-
format: jsonFileFormat,
|
|
124
|
-
maxSize: "2mb",
|
|
125
|
-
maxFiles: "7d"
|
|
126
|
-
}),
|
|
127
|
-
new winston.transports.DailyRotateFile({
|
|
128
|
-
filename: path.resolve(loadPath, "critical", "%DATE%_critical.log"),
|
|
129
|
-
level: "critical",
|
|
130
|
-
format: jsonFileFormat,
|
|
131
|
-
maxSize: "2mb",
|
|
132
|
-
maxFiles: "14d"
|
|
133
|
-
})
|
|
134
|
-
]
|
|
135
|
-
});
|
|
136
|
-
winstonLogger.on("data", (info) => {
|
|
137
|
-
if (this.isKafkaReady) {
|
|
138
|
-
this.logToKafka(info);
|
|
139
|
-
}
|
|
146
|
+
transports
|
|
140
147
|
});
|
|
141
148
|
this.winston = winstonLogger;
|
|
142
149
|
return winstonLogger;
|
|
@@ -150,13 +157,13 @@ export default class LoggerService {
|
|
|
150
157
|
topic: this.kafkaTopic,
|
|
151
158
|
messages: [{
|
|
152
159
|
value: JSON.stringify({
|
|
153
|
-
|
|
160
|
+
id: id || null,
|
|
154
161
|
service: this.serviceName,
|
|
162
|
+
env: this.environment,
|
|
155
163
|
level,
|
|
156
164
|
message,
|
|
157
165
|
...rest,
|
|
158
|
-
|
|
159
|
-
env: this.environment,
|
|
166
|
+
timestamp: new Date().toISOString()
|
|
160
167
|
}, this.safeReplacer)
|
|
161
168
|
}]
|
|
162
169
|
});
|