UNPKG

21.3 kBJavaScriptView Raw
1"use strict";
2var __importDefault = (this && this.__importDefault) || function (mod) {
3 return (mod && mod.__esModule) ? mod : { "default": mod };
4};
5Object.defineProperty(exports, "__esModule", { value: true });
6const mkdirp_1 = __importDefault(require("mkdirp"));
7const fs_1 = require("fs");
8const path_1 = require("path");
9const words_1 = __importDefault(require("./words"));
10const colors_1 = __importDefault(require("colors"));
11const find_up_1 = __importDefault(require("find-up"));
12const nodemailer_1 = __importDefault(require("nodemailer"));
13class 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}
21exports.BaseException = BaseException;
22class ClientException extends BaseException {
23}
24exports.ClientException = ClientException;
25class ExternalException extends BaseException {
26}
27exports.ExternalException = ExternalException;
28class Exception extends BaseException {
29}
30exports.Exception = Exception;
31class 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}
103exports.Logger = Logger;
104class LoggerOpened extends Logger {
105 setSettings(_settings) { }
106}
107class LoggerStream {
108 constructor(level) {
109 this.level = level;
110 }
111}
112class 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}
141class 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}
175class 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}
201function 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}
225const levels = {
226 error: 0,
227 warn: 1,
228 external: 2,
229 info: 3,
230 clientError: 4,
231 trace: 5,
232};
233const packageJsonFile = find_up_1.default.sync('package.json', { cwd: require.main.filename });
234if (!packageJsonFile)
235 throw new Exception('package.json is not found');
236exports.logger = new Logger({ streams: [] });
237const extractPathRegex = /\s+at.*?\((.*?)\)/;
238const pathRegex = /^internal|(.*?\/node_modules\/(ts-node)\/)/;
239function 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}
255function setLoggerSettings(settings) {
256 exports.logger.setSettings(settings);
257}
258exports.setLoggerSettings = setLoggerSettings;
259//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2xvZ2dlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLG9EQUE0QjtBQUM1QiwyQkFBd0U7QUFDeEUsK0JBQStCO0FBQy9CLG9EQUE0QjtBQUM1QixvREFBNEI7QUFDNUIsc0RBQTZCO0FBRTdCLDREQUFvQztBQUVwQyxNQUFhLGFBQWlCLFNBQVEsS0FBSztJQUUxQyxZQUFtQixJQUFZLEVBQVMsT0FBTyxFQUFPO1FBQ3JELEtBQUssRUFBRSxDQUFDO1FBRFUsU0FBSSxHQUFKLElBQUksQ0FBUTtRQUFTLFNBQUksR0FBSixJQUFJLENBQVU7UUFFckQsSUFBSSxDQUFDLElBQUksR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztJQUM3QixDQUFDO0NBQ0Q7QUFORCxzQ0FNQztBQUNELE1BQWEsZUFBNEIsU0FBUSxhQUFnQjtDQUFHO0FBQXBFLDBDQUFvRTtBQUNwRSxNQUFhLGlCQUE4QixTQUFRLGFBQWdCO0NBQUc7QUFBdEUsOENBQXNFO0FBQ3RFLE1BQWEsU0FBc0IsU0FBUSxhQUFnQjtDQUFHO0FBQTlELDhCQUE4RDtBQW1COUQsTUFBYSxNQUFNO0lBRWxCLFlBQVksUUFBd0I7UUFEMUIsWUFBTyxHQUFtQixFQUFFLENBQUM7UUFFdEMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUM1QixDQUFDO0lBRVMsV0FBVyxDQUFDLFFBQXdCO1FBQzdDLEtBQUssTUFBTSxZQUFZLElBQUksUUFBUSxDQUFDLE9BQU8sRUFBRTtZQUM1QyxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3pDLElBQUksWUFBWSxDQUFDLElBQUksS0FBSyxNQUFNLEVBQUU7Z0JBQ2pDLGNBQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksVUFBVSxDQUFDLEtBQUssRUFBRSxZQUFZLENBQUMsQ0FB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
\No newline at end of file