1 | ;
|
2 | var __importDefault = (this && this.__importDefault) || function (mod) {
|
3 | return (mod && mod.__esModule) ? mod : { "default": mod };
|
4 | };
|
5 | Object.defineProperty(exports, "__esModule", { value: true });
|
6 | const mkdirp_1 = __importDefault(require("mkdirp"));
|
7 | const fs_1 = require("fs");
|
8 | const path_1 = require("path");
|
9 | const words_1 = __importDefault(require("./words"));
|
10 | const colors_1 = __importDefault(require("colors"));
|
11 | const find_up_1 = __importDefault(require("find-up"));
|
12 | const nodemailer_1 = __importDefault(require("nodemailer"));
|
13 | class BaseException extends Error {
|
14 | constructor(name, json = {}) {
|
15 | super();
|
16 | this.name = name;
|
17 | this.json = json;
|
18 | this.kind = new.target.name;
|
19 | }
|
20 | }
|
21 | exports.BaseException = BaseException;
|
22 | class ClientException extends BaseException {
|
23 | }
|
24 | exports.ClientException = ClientException;
|
25 | class ExternalException extends BaseException {
|
26 | }
|
27 | exports.ExternalException = ExternalException;
|
28 | class Exception extends BaseException {
|
29 | }
|
30 | exports.Exception = Exception;
|
31 | class Logger {
|
32 | constructor(settings) {
|
33 | this.streams = [];
|
34 | this.setSettings(settings);
|
35 | }
|
36 | setSettings(settings) {
|
37 | for (const streamConfig of settings.streams) {
|
38 | const level = levels[streamConfig.level];
|
39 | if (streamConfig.type === 'file') {
|
40 | exports.logger.streams.push(new FileStream(level, streamConfig));
|
41 | }
|
42 | if (streamConfig.type === 'stdout') {
|
43 | exports.logger.streams.push(new StdoutStream(level, streamConfig));
|
44 | }
|
45 | if (streamConfig.type === 'email') {
|
46 | exports.logger.streams.push(new EmailStream(level, streamConfig));
|
47 | }
|
48 | }
|
49 | }
|
50 | log(type, name, json) {
|
51 | if (this.streams.length === 0)
|
52 | throw new Exception('Empty logger streams');
|
53 | if (json === undefined)
|
54 | json = {};
|
55 | if (!(json instanceof Object))
|
56 | json = { raw: json };
|
57 | const id = words_1.default[Math.floor(words_1.default.length * Math.random())];
|
58 | const parentId = '';
|
59 | const date = new Date();
|
60 | for (const stream of this.streams) {
|
61 | if (levels[type] <= stream.level) {
|
62 | stream.write(id, parentId, date, type, name, json);
|
63 | }
|
64 | }
|
65 | }
|
66 | info(name, json) {
|
67 | return this.log('info', name, json);
|
68 | }
|
69 | clientError(name, json) {
|
70 | return this.log('clientError', name, json);
|
71 | }
|
72 | warn(name, json) {
|
73 | return this.log('warn', name, json);
|
74 | }
|
75 | trace(name, json) {
|
76 | return this.log('trace', name, json);
|
77 | }
|
78 | error(name, json) {
|
79 | if (name instanceof Error) {
|
80 | const error = name;
|
81 | if (error instanceof BaseException) {
|
82 | if (error.kind === ClientException.name) {
|
83 | return this.clientError(error.name, error);
|
84 | }
|
85 | if (error.kind === ExternalException.name) {
|
86 | return this.external(error.name, error);
|
87 | }
|
88 | if (error.kind === Exception.name) {
|
89 | return this.log('error', error.name, error);
|
90 | }
|
91 | }
|
92 | return this.log('error', error.constructor.name, error);
|
93 | }
|
94 | if (typeof name !== 'string') {
|
95 | return this.log('error', 'Raw error', name instanceof Object ? name : { error: name });
|
96 | }
|
97 | return this.log('error', name, json);
|
98 | }
|
99 | external(name, json) {
|
100 | return this.log('external', name, json);
|
101 | }
|
102 | }
|
103 | exports.Logger = Logger;
|
104 | class LoggerOpened extends Logger {
|
105 | setSettings(_settings) { }
|
106 | }
|
107 | class LoggerStream {
|
108 | constructor(level) {
|
109 | this.level = level;
|
110 | }
|
111 | }
|
112 | class EmailStream extends LoggerStream {
|
113 | constructor(level, options) {
|
114 | super(level);
|
115 | this.options = options;
|
116 | this.transport = nodemailer_1.default.createTransport(this.options.options);
|
117 | this.lastSendedAt = new Date(0);
|
118 | this.previousLogsCount = 0;
|
119 | this.sendMail(this.options.subject.start, '');
|
120 | }
|
121 | sendMail(subject, text) {
|
122 | this.transport
|
123 | .sendMail({
|
124 | to: this.options.to,
|
125 | from: this.options.from,
|
126 | subject,
|
127 | text,
|
128 | })
|
129 | .catch(err => exports.logger.error(err));
|
130 | }
|
131 | write(_id, _parentId, date, type, name, json) {
|
132 | if (Date.now() - this.lastSendedAt.getTime() < 3600000) {
|
133 | this.previousLogsCount++;
|
134 | return;
|
135 | }
|
136 | this.sendMail(this.options.subject.error, `${this.previousLogsCount > 0 ? `Prev errors count: ${this.previousLogsCount}\n` : ''}${date.toISOString()} ${type} ${name} ${JSON.stringify(json, jsonReplacer, 2)}`);
|
137 | this.lastSendedAt = new Date();
|
138 | this.previousLogsCount = 0;
|
139 | }
|
140 | }
|
141 | class FileStream extends LoggerStream {
|
142 | constructor(level, options) {
|
143 | super(level);
|
144 | this.options = options;
|
145 | mkdirp_1.default.sync(path_1.dirname(options.file));
|
146 | let createdAt = new Date();
|
147 | try {
|
148 | createdAt = fs_1.fstatSync(fs_1.openSync(options.file, 'r')).ctime;
|
149 | }
|
150 | catch (e) { }
|
151 | this.stream = fs_1.createWriteStream(options.file, { flags: 'a' });
|
152 | this.createdAt = createdAt;
|
153 | this.rotate = options.rotate || 'never';
|
154 | this.fileName = options.file;
|
155 | }
|
156 | selectFile() {
|
157 | const d = new Date();
|
158 | if (this.rotate === 'daily') {
|
159 | const d2 = this.createdAt;
|
160 | if (d.getDate() !== d2.getDate() || d.getMonth() !== d2.getMonth() || d.getFullYear() !== d2.getFullYear()) {
|
161 | this.stream.end();
|
162 | const historyName = this.fileName.replace(/\.log$/, '') + '_' + this.createdAt.toISOString().split('T')[0] + '.log';
|
163 | fs_1.renameSync(this.fileName, historyName);
|
164 | this.stream = fs_1.createWriteStream(this.fileName);
|
165 | this.createdAt = new Date();
|
166 | }
|
167 | }
|
168 | }
|
169 | write(id, parentId, date, type, name, json) {
|
170 | this.selectFile();
|
171 | const str = JSON.stringify([id, parentId, date, type, name, json], jsonReplacer) + '\n';
|
172 | this.stream.write(str);
|
173 | }
|
174 | }
|
175 | class StdoutStream extends LoggerStream {
|
176 | constructor(level, _options) {
|
177 | super(level);
|
178 | }
|
179 | write(_id, _parentId, date, type, name, json) {
|
180 | let fn = colors_1.default.black;
|
181 | if (type === 'error')
|
182 | fn = colors_1.default.red.bold;
|
183 | if (type === 'info')
|
184 | fn = colors_1.default.cyan;
|
185 | if (type === 'warn')
|
186 | fn = colors_1.default.yellow;
|
187 | if (type === 'trace')
|
188 | fn = colors_1.default.gray;
|
189 | if (type === 'external')
|
190 | fn = colors_1.default.magenta;
|
191 | if (type === 'clientError')
|
192 | fn = colors_1.default.green;
|
193 | const dtS = ('0' + date.getHours()).substr(-2) +
|
194 | ':' +
|
195 | ('0' + date.getMinutes()).substr(-2) +
|
196 | ':' +
|
197 | ('0' + date.getSeconds()).substr(-2);
|
198 | process.stdout.write(colors_1.default.gray(dtS + ' ' + type + ' ') + fn(name + ' ') + colors_1.default.gray(JSON.stringify(json, jsonReplacer, 2) + '\n'));
|
199 | }
|
200 | }
|
201 | function jsonReplacer(_key, value) {
|
202 | if (value instanceof Error) {
|
203 | const stack = cleanStackTrace(value.stack);
|
204 | if (value instanceof BaseException) {
|
205 | return { name: value.name, stack, json: value.json };
|
206 | }
|
207 | return { ...value, error: value.message, stack };
|
208 | }
|
209 | if (value instanceof Object) {
|
210 | if ('request' in value && 'headers' in value && 'body' in value && 'statusCode' in value) {
|
211 | return { __type: 'responseObject' };
|
212 | }
|
213 | if ('method' in value && 'uri' in value && 'headers' in value) {
|
214 | return { __type: 'requestObject' };
|
215 | }
|
216 | if (value instanceof Promise) {
|
217 | return { __type: 'promise' };
|
218 | }
|
219 | if (value instanceof Buffer) {
|
220 | return { __type: 'buffer' };
|
221 | }
|
222 | }
|
223 | return value;
|
224 | }
|
225 | const levels = {
|
226 | error: 0,
|
227 | warn: 1,
|
228 | external: 2,
|
229 | info: 3,
|
230 | clientError: 4,
|
231 | trace: 5,
|
232 | };
|
233 | const packageJsonFile = find_up_1.default.sync('package.json', { cwd: require.main.filename });
|
234 | if (!packageJsonFile)
|
235 | throw new Exception('package.json is not found');
|
236 | exports.logger = new Logger({ streams: [] });
|
237 | const extractPathRegex = /\s+at.*?\((.*?)\)/;
|
238 | const pathRegex = /^internal|(.*?\/node_modules\/(ts-node)\/)/;
|
239 | function cleanStackTrace(stack) {
|
240 | if (!stack)
|
241 | return;
|
242 | return stack
|
243 | .replace(/\\/g, '/')
|
244 | .split('\n')
|
245 | .filter(line => {
|
246 | const pathMatches = line.match(extractPathRegex);
|
247 | if (pathMatches === null)
|
248 | return true;
|
249 | const match = pathMatches[1];
|
250 | return !pathRegex.test(match);
|
251 | })
|
252 | .filter(line => line.trim() !== '')
|
253 | .join('\n');
|
254 | }
|
255 | function setLoggerSettings(settings) {
|
256 | exports.logger.setSettings(settings);
|
257 | }
|
258 | exports.setLoggerSettings = setLoggerSettings;
|
259 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2xvZ2dlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLG9EQUE0QjtBQUM1QiwyQkFBd0U7QUFDeEUsK0JBQStCO0FBQy9CLG9EQUE0QjtBQUM1QixvREFBNEI7QUFDNUIsc0RBQTZCO0FBRTdCLDREQUFvQztBQUVwQyxNQUFhLGFBQWlCLFNBQVEsS0FBSztJQUUxQyxZQUFtQixJQUFZLEVBQVMsT0FBTyxFQUFPO1FBQ3JELEtBQUssRUFBRSxDQUFDO1FBRFUsU0FBSSxHQUFKLElBQUksQ0FBUTtRQUFTLFNBQUksR0FBSixJQUFJLENBQVU7UUFFckQsSUFBSSxDQUFDLElBQUksR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztJQUM3QixDQUFDO0NBQ0Q7QUFORCxzQ0FNQztBQUNELE1BQWEsZUFBNEIsU0FBUSxhQUFnQjtDQUFHO0FBQXBFLDBDQUFvRTtBQUNwRSxNQUFhLGlCQUE4QixTQUFRLGFBQWdCO0NBQUc7QUFBdEUsOENBQXNFO0FBQ3RFLE1BQWEsU0FBc0IsU0FBUSxhQUFnQjtDQUFHO0FBQTlELDhCQUE4RDtBQW1COUQsTUFBYSxNQUFNO0lBRWxCLFlBQVksUUFBd0I7UUFEMUIsWUFBTyxHQUFtQixFQUFFLENBQUM7UUFFdEMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUM1QixDQUFDO0lBRVMsV0FBVyxDQUFDLFFBQXdCO1FBQzdDLEtBQUssTUFBTSxZQUFZLElBQUksUUFBUSxDQUFDLE9BQU8sRUFBRTtZQUM1QyxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3pDLElBQUksWUFBWSxDQUFDLElBQUksS0FBSyxNQUFNLEVBQUU7Z0JBQ2pDLGNBQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksVUFBVSxDQUFDLEtBQUssRUFBRSxZQUFZLENBQUMsQ0FB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 |
\ | No newline at end of file |