infront-logger 1.0.1 → 1.0.4

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/README.MD CHANGED
@@ -6,11 +6,113 @@ The logger supports both writhing to file and to console.
6
6
  npm i @infront/logger
7
7
 
8
8
  ## Usage
9
+
10
+ ### BaseLogger
9
11
  const {BaseLogger} = require('infront-logger');
10
12
  let options = {};
11
13
  let logger = new BaseLogger("component1", options);
12
14
  logger.log("this is a test message");
13
15
 
16
+ ### HttpLogger
17
+ const {HttpLogger} = require('infront-logger');
18
+
19
+ const responseInterceptor = (req, res, next) => {
20
+ // Save the original response method
21
+
22
+ const originalSend = res.send;
23
+ const originalJSON = res.json;
24
+ const originalSendStatus = res.sendStatus;
25
+
26
+ let responseSent = false;
27
+ let startTime = Date.now();
28
+
29
+ // Override the response method
30
+ res.sendStatus = function(status){
31
+ try{
32
+ const httpLogger = new HttpLogger();
33
+ if (!responseSent) {
34
+ res.statusCode = status;
35
+ httpLogger.request(req);
36
+ httpLogger.response(res);
37
+
38
+
39
+ if (status < 400) {
40
+ httpLogger.success();
41
+ } else {
42
+ httpLogger.error("req.sendStatus with error status");
43
+ }
44
+ responseSent = true;
45
+ }
46
+ } catch (err){
47
+ console.error(err);
48
+
49
+ }
50
+ return originalSendStatus.call(this, status);
51
+ };
52
+
53
+ res.send = function (body){
54
+ try{
55
+ const httpLogger = new HttpLogger();
56
+ if (!responseSent) {
57
+ httpLogger.request(req);
58
+ httpLogger.response(res);
59
+ httpLogger.body(body);
60
+ if (res.statusCode < 400) {
61
+ httpLogger.success();
62
+ } else {
63
+ httpLogger.error(body.message);
64
+ }
65
+ responseSent = true;
66
+ }
67
+ } catch (err){
68
+ console.error(err);
69
+ }
70
+
71
+ // Call the original response method
72
+ return originalSend.call(this, body);
73
+ };
74
+
75
+
76
+ res.json = function (body){
77
+ try{
78
+ const httpLogger = new HttpLogger();
79
+ if (!responseSent) {
80
+ httpLogger.request(req).response(res).body(body);
81
+
82
+ if (res.statusCode < 400) {
83
+ httpLogger.success();
84
+ } else {
85
+ httpLogger.error(body.message);
86
+ }
87
+ responseSent = true;
88
+ }
89
+
90
+
91
+ } catch (err){
92
+ console.error(err);
93
+ }
94
+
95
+ // Call the original response method
96
+ return originalJSON.call(this, body);
97
+ };
98
+
99
+ // Continue processing the request
100
+ next();
101
+ }
102
+
103
+ app.use(responseInterceptor);
104
+
105
+
106
+
107
+
108
+ ### MongooseLoggerPlugin
109
+ Make sure to use before defining schemas;
110
+
111
+ const {MongooseLoggerPlugin} = require('infront-logger');
112
+ const mongoose = require('mongoose');
113
+ let plugin = MongooseLoggerPlugin({console : false, filename : 'db.log'});
114
+ mongoose.plugin(plugin);
115
+
14
116
  ## Loggers
15
117
 
16
118
  ### BaseLogger
@@ -36,8 +138,10 @@ The logger supports both writhing to file and to console.
36
138
  - levels - An object of "level name : hierarchical value"
37
139
  - level - default level (default: info)
38
140
  - dateFormat : default "YYYY-MM-DD HH:mm:ss:ms"
141
+ - file - boolean - should log to file (default : true)
39
142
  - maxFileSize: The maximum file size for a rotating file strategy (default: "30m")
40
143
  - maxFiles: The maximum number of files for a rotating file strategy (default: 2)
41
144
  - filename - name of the default log file (default: "logs.log")
42
145
  - errorFilename - name of the default error log file (default: "error.log")
43
146
  - console - boolean - should log to console (default: true)
147
+ - consoleJSON - boolean - print full json to console (default : false)
package/dist/index.es.js CHANGED
@@ -1,6 +1,6 @@
1
1
  require("winston-daily-rotate-file");
2
2
  const { format: format$1, createLogger, transports, addColors } = require("winston");
3
- const { inspect } = require("util");
3
+ require("util");
4
4
  const colors = {
5
5
  error: "red",
6
6
  warn: "yellow",
@@ -26,47 +26,56 @@ const OPTIONS = {
26
26
  filename: "logs.log",
27
27
  errorFilename: "error.log",
28
28
  console: true,
29
+ file: true,
29
30
  exclude: [],
30
31
  createSymlink: true,
31
- symlinkName: "logs.log"
32
+ symlinkName: "logs.log",
33
+ consoleJSON: false
32
34
  };
33
- function errorToJSON(error) {
34
- const { message, name, stack } = error;
35
- return {
36
- message,
37
- name,
38
- stack
39
- };
40
- }
41
35
  function fileFormatter(options) {
42
36
  return format$1.combine(
43
- // format.errors({stack: true}),
44
- {
45
- transform: (info) => {
46
- const args = [info.message, ...info[Symbol.for("splat")] || []];
47
- info.message = args.filter(Boolean).map((arg) => {
48
- if (arg instanceof Error) {
49
- return errorToJSON(arg);
50
- }
51
- return arg;
52
- });
53
- const msg = args.map((arg) => {
54
- if (typeof arg == "object")
55
- return inspect(arg, { compact: false, depth: Infinity });
56
- return arg;
57
- }).join(" ");
58
- info[Symbol.for("message")] = `${info[Symbol.for("level")]}: ${msg}${info.stack ? " " + info.stack : ""}`;
59
- if (options.exclude.some((string) => msg.includes(string)))
60
- return null;
61
- return info;
62
- }
63
- },
37
+ format$1.errors({ stack: true }),
38
+ // {
39
+ // transform: (info) => {
40
+ // const args = [info.message, ...(info[Symbol.for('splat')] || [])];
41
+ // info.message = args.filter(Boolean).map(arg => {
42
+ // if(arg instanceof Error){
43
+ // return errorToJSON(arg);
44
+ // }
45
+ // return arg;
46
+ // });
47
+ //
48
+ // const msg = args.map(arg => {
49
+ // if (typeof arg == 'object')
50
+ // return inspect(arg, {compact: false, depth: Infinity});
51
+ // return arg;
52
+ // }).join(' ');
53
+ //
54
+ // info[Symbol.for('message')] = `${info[Symbol.for('level')]}: ${msg}${info.stack ? ' ' + info.stack : ''}`;
55
+ //
56
+ // if(options.exclude.some(string => msg.includes(string))) return null;
57
+ //
58
+ // return info;
59
+ // }
60
+ // },
64
61
  format$1.timestamp({ format: options.dateFormat }),
65
62
  format$1.json()
66
63
  );
67
64
  }
68
65
  function consoleFormatter(options) {
69
- return format$1.timestamp({ format: options.dateFormat }), format$1.colorize({ all: true });
66
+ return format$1.combine(
67
+ format$1.errors({ stack: true }),
68
+ format$1.printf((info) => {
69
+ if ((info == null ? void 0 : info.level) === "error" && info.stack) {
70
+ return `${info.stack}`;
71
+ } else {
72
+ return info.message;
73
+ }
74
+ }),
75
+ // options.consoleJSON? format.json() : {transform : (info)=>info},
76
+ options.consoleJSON ? format$1.json() : format$1.splat(),
77
+ format$1.colorize({ all: true })
78
+ );
70
79
  }
71
80
  function getFormatter(type, options) {
72
81
  switch (type) {
@@ -90,19 +99,32 @@ function createTransport(options) {
90
99
  class Logger {
91
100
  constructor(options = {}) {
92
101
  this.options = { ...OPTIONS, ...options };
93
- let trans = [
94
- createTransport({
102
+ if (!this.options.filename.includes("."))
103
+ this.options.filename += ".log";
104
+ if (!this.options.errorFilename.includes("."))
105
+ this.options.errorFilename += ".log";
106
+ let trans = [];
107
+ let exceptionHandlers = [new transports.Console({
108
+ format: getFormatter("console", this.options)
109
+ })];
110
+ if (this.options.file) {
111
+ trans.push(createTransport({
95
112
  ...this.options,
113
+ format: "file",
96
114
  filename: this.options.filename,
97
115
  symlinkName: this.options.filename
98
- }),
99
- createTransport({
116
+ }));
117
+ trans.push(createTransport({
100
118
  ...this.options,
119
+ format: "file",
101
120
  filename: this.options.errorFilename,
102
121
  symlinkName: this.options.errorFilename,
103
122
  level: "error"
104
- })
105
- ];
123
+ }));
124
+ exceptionHandlers.push(
125
+ new transports.File({ filename: `${this.options.dirname}/${this.options.errorFilename}` })
126
+ );
127
+ }
106
128
  if (this.options.console) {
107
129
  trans.push(new transports.Console({
108
130
  format: getFormatter("console", this.options)
@@ -114,10 +136,7 @@ class Logger {
114
136
  exitOnError: false,
115
137
  // format,
116
138
  transports: trans,
117
- exceptionHandlers: [
118
- new transports.Console(),
119
- new transports.File({ filename: `${this.options.dirname}/${this.options.errorFilename}` })
120
- ]
139
+ exceptionHandlers
121
140
  });
122
141
  }
123
142
  }
@@ -349,7 +368,83 @@ class HTTPLogger extends BaseLogger {
349
368
  super.error(this._message(err));
350
369
  }
351
370
  }
371
+ const ops = [
372
+ "find",
373
+ "findOne",
374
+ "findById",
375
+ "findOneAndUpdate",
376
+ "updateOne",
377
+ "updateMany",
378
+ "countDocuments",
379
+ "estimatedDocumentCount",
380
+ "findOneAndRemove",
381
+ "findOneAndDelete",
382
+ "deleteOne",
383
+ "deleteMany",
384
+ "aggregate",
385
+ "save"
386
+ ];
387
+ const MAX_RESULT_BYTES = 100 * 1024;
388
+ class MongooseLogger extends BaseLogger {
389
+ constructor(options = {}) {
390
+ super("database", options);
391
+ }
392
+ operation(o) {
393
+ this.ctx.operation = o;
394
+ return this;
395
+ }
396
+ collection(c) {
397
+ this.ctx.collection = c;
398
+ return this;
399
+ }
400
+ query(q) {
401
+ this.ctx.query = q;
402
+ return this;
403
+ }
404
+ update(u) {
405
+ this.ctx.update = u;
406
+ return this;
407
+ }
408
+ pipeline(p) {
409
+ this.ctx.pipeline = p;
410
+ return this;
411
+ }
412
+ result(res) {
413
+ try {
414
+ this.ctx.resultSizeBytes = JSON.stringify(res).length;
415
+ } catch (err) {
416
+ }
417
+ if (Array.isArray(res)) {
418
+ this.ctx.documentCount = res.length;
419
+ } else if (this.ctx.resultSizeBytes < MAX_RESULT_BYTES) {
420
+ this.ctx.result = res;
421
+ } else {
422
+ this.ctx.result = `Result too long (more then ${MAX_RESULT_BYTES} bytes)`;
423
+ }
424
+ return this;
425
+ }
426
+ }
427
+ function postHook(target, res) {
428
+ var _a, _b, _c, _d, _e;
429
+ const op = target.constructor.name === "Aggregate" ? "aggregate" : target.op || target.$op;
430
+ const collection = ((_a = target == null ? void 0 : target._collection) == null ? void 0 : _a.collectionName) || ((_b = target == null ? void 0 : target.collection) == null ? void 0 : _b.name) || ((_d = (_c = target == null ? void 0 : target._model) == null ? void 0 : _c.collection) == null ? void 0 : _d.collectionName);
431
+ (_e = target == null ? void 0 : target.logger) == null ? void 0 : _e.operation(op).collection(collection).query(target._conditions).update(target._update).pipeline(target._pipeline).profile().result(res).info(`DB query: ${op} - ${collection}`);
432
+ }
433
+ function plugin(options = {}) {
434
+ return (schema) => {
435
+ ops.forEach((op) => {
436
+ schema.pre(op, function(next) {
437
+ this.logger = new MongooseLogger(options);
438
+ next();
439
+ });
440
+ schema.post(op, function(res) {
441
+ postHook(this, res);
442
+ });
443
+ });
444
+ };
445
+ }
352
446
  export {
353
447
  BaseLogger,
354
- HTTPLogger as HttpLogger
448
+ HTTPLogger as HttpLogger,
449
+ plugin as MongooseLoggerPlugin
355
450
  };
package/dist/index.umd.js CHANGED
@@ -4,7 +4,7 @@
4
4
  "use strict";
5
5
  require("winston-daily-rotate-file");
6
6
  const { format: format$1, createLogger, transports, addColors } = require("winston");
7
- const { inspect } = require("util");
7
+ require("util");
8
8
  const colors = {
9
9
  error: "red",
10
10
  warn: "yellow",
@@ -30,47 +30,56 @@
30
30
  filename: "logs.log",
31
31
  errorFilename: "error.log",
32
32
  console: true,
33
+ file: true,
33
34
  exclude: [],
34
35
  createSymlink: true,
35
- symlinkName: "logs.log"
36
+ symlinkName: "logs.log",
37
+ consoleJSON: false
36
38
  };
37
- function errorToJSON(error) {
38
- const { message, name, stack } = error;
39
- return {
40
- message,
41
- name,
42
- stack
43
- };
44
- }
45
39
  function fileFormatter(options) {
46
40
  return format$1.combine(
47
- // format.errors({stack: true}),
48
- {
49
- transform: (info) => {
50
- const args = [info.message, ...info[Symbol.for("splat")] || []];
51
- info.message = args.filter(Boolean).map((arg) => {
52
- if (arg instanceof Error) {
53
- return errorToJSON(arg);
54
- }
55
- return arg;
56
- });
57
- const msg = args.map((arg) => {
58
- if (typeof arg == "object")
59
- return inspect(arg, { compact: false, depth: Infinity });
60
- return arg;
61
- }).join(" ");
62
- info[Symbol.for("message")] = `${info[Symbol.for("level")]}: ${msg}${info.stack ? " " + info.stack : ""}`;
63
- if (options.exclude.some((string) => msg.includes(string)))
64
- return null;
65
- return info;
66
- }
67
- },
41
+ format$1.errors({ stack: true }),
42
+ // {
43
+ // transform: (info) => {
44
+ // const args = [info.message, ...(info[Symbol.for('splat')] || [])];
45
+ // info.message = args.filter(Boolean).map(arg => {
46
+ // if(arg instanceof Error){
47
+ // return errorToJSON(arg);
48
+ // }
49
+ // return arg;
50
+ // });
51
+ //
52
+ // const msg = args.map(arg => {
53
+ // if (typeof arg == 'object')
54
+ // return inspect(arg, {compact: false, depth: Infinity});
55
+ // return arg;
56
+ // }).join(' ');
57
+ //
58
+ // info[Symbol.for('message')] = `${info[Symbol.for('level')]}: ${msg}${info.stack ? ' ' + info.stack : ''}`;
59
+ //
60
+ // if(options.exclude.some(string => msg.includes(string))) return null;
61
+ //
62
+ // return info;
63
+ // }
64
+ // },
68
65
  format$1.timestamp({ format: options.dateFormat }),
69
66
  format$1.json()
70
67
  );
71
68
  }
72
69
  function consoleFormatter(options) {
73
- return format$1.timestamp({ format: options.dateFormat }), format$1.colorize({ all: true });
70
+ return format$1.combine(
71
+ format$1.errors({ stack: true }),
72
+ format$1.printf((info) => {
73
+ if ((info == null ? void 0 : info.level) === "error" && info.stack) {
74
+ return `${info.stack}`;
75
+ } else {
76
+ return info.message;
77
+ }
78
+ }),
79
+ // options.consoleJSON? format.json() : {transform : (info)=>info},
80
+ options.consoleJSON ? format$1.json() : format$1.splat(),
81
+ format$1.colorize({ all: true })
82
+ );
74
83
  }
75
84
  function getFormatter(type, options) {
76
85
  switch (type) {
@@ -94,19 +103,32 @@
94
103
  class Logger {
95
104
  constructor(options = {}) {
96
105
  this.options = { ...OPTIONS, ...options };
97
- let trans = [
98
- createTransport({
106
+ if (!this.options.filename.includes("."))
107
+ this.options.filename += ".log";
108
+ if (!this.options.errorFilename.includes("."))
109
+ this.options.errorFilename += ".log";
110
+ let trans = [];
111
+ let exceptionHandlers = [new transports.Console({
112
+ format: getFormatter("console", this.options)
113
+ })];
114
+ if (this.options.file) {
115
+ trans.push(createTransport({
99
116
  ...this.options,
117
+ format: "file",
100
118
  filename: this.options.filename,
101
119
  symlinkName: this.options.filename
102
- }),
103
- createTransport({
120
+ }));
121
+ trans.push(createTransport({
104
122
  ...this.options,
123
+ format: "file",
105
124
  filename: this.options.errorFilename,
106
125
  symlinkName: this.options.errorFilename,
107
126
  level: "error"
108
- })
109
- ];
127
+ }));
128
+ exceptionHandlers.push(
129
+ new transports.File({ filename: `${this.options.dirname}/${this.options.errorFilename}` })
130
+ );
131
+ }
110
132
  if (this.options.console) {
111
133
  trans.push(new transports.Console({
112
134
  format: getFormatter("console", this.options)
@@ -118,10 +140,7 @@
118
140
  exitOnError: false,
119
141
  // format,
120
142
  transports: trans,
121
- exceptionHandlers: [
122
- new transports.Console(),
123
- new transports.File({ filename: `${this.options.dirname}/${this.options.errorFilename}` })
124
- ]
143
+ exceptionHandlers
125
144
  });
126
145
  }
127
146
  }
@@ -353,7 +372,83 @@
353
372
  super.error(this._message(err));
354
373
  }
355
374
  }
375
+ const ops = [
376
+ "find",
377
+ "findOne",
378
+ "findById",
379
+ "findOneAndUpdate",
380
+ "updateOne",
381
+ "updateMany",
382
+ "countDocuments",
383
+ "estimatedDocumentCount",
384
+ "findOneAndRemove",
385
+ "findOneAndDelete",
386
+ "deleteOne",
387
+ "deleteMany",
388
+ "aggregate",
389
+ "save"
390
+ ];
391
+ const MAX_RESULT_BYTES = 100 * 1024;
392
+ class MongooseLogger extends BaseLogger {
393
+ constructor(options = {}) {
394
+ super("database", options);
395
+ }
396
+ operation(o) {
397
+ this.ctx.operation = o;
398
+ return this;
399
+ }
400
+ collection(c) {
401
+ this.ctx.collection = c;
402
+ return this;
403
+ }
404
+ query(q) {
405
+ this.ctx.query = q;
406
+ return this;
407
+ }
408
+ update(u) {
409
+ this.ctx.update = u;
410
+ return this;
411
+ }
412
+ pipeline(p) {
413
+ this.ctx.pipeline = p;
414
+ return this;
415
+ }
416
+ result(res) {
417
+ try {
418
+ this.ctx.resultSizeBytes = JSON.stringify(res).length;
419
+ } catch (err) {
420
+ }
421
+ if (Array.isArray(res)) {
422
+ this.ctx.documentCount = res.length;
423
+ } else if (this.ctx.resultSizeBytes < MAX_RESULT_BYTES) {
424
+ this.ctx.result = res;
425
+ } else {
426
+ this.ctx.result = `Result too long (more then ${MAX_RESULT_BYTES} bytes)`;
427
+ }
428
+ return this;
429
+ }
430
+ }
431
+ function postHook(target, res) {
432
+ var _a, _b, _c, _d, _e;
433
+ const op = target.constructor.name === "Aggregate" ? "aggregate" : target.op || target.$op;
434
+ const collection = ((_a = target == null ? void 0 : target._collection) == null ? void 0 : _a.collectionName) || ((_b = target == null ? void 0 : target.collection) == null ? void 0 : _b.name) || ((_d = (_c = target == null ? void 0 : target._model) == null ? void 0 : _c.collection) == null ? void 0 : _d.collectionName);
435
+ (_e = target == null ? void 0 : target.logger) == null ? void 0 : _e.operation(op).collection(collection).query(target._conditions).update(target._update).pipeline(target._pipeline).profile().result(res).info(`DB query: ${op} - ${collection}`);
436
+ }
437
+ function plugin(options = {}) {
438
+ return (schema) => {
439
+ ops.forEach((op) => {
440
+ schema.pre(op, function(next) {
441
+ this.logger = new MongooseLogger(options);
442
+ next();
443
+ });
444
+ schema.post(op, function(res) {
445
+ postHook(this, res);
446
+ });
447
+ });
448
+ };
449
+ }
356
450
  exports2.BaseLogger = BaseLogger;
357
451
  exports2.HttpLogger = HTTPLogger;
452
+ exports2.MongooseLoggerPlugin = plugin;
358
453
  Object.defineProperty(exports2, Symbol.toStringTag, { value: "Module" });
359
454
  });
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "infront-logger",
3
- "version": "1.0.1",
3
+ "version": "1.0.4",
4
4
  "description": "",
5
5
  "files": [
6
6
  "dist"
7
7
  ],
8
8
  "main": "./dist/index.umd.js",
9
9
  "module": "./dist/index.es.js",
10
+ "types": "./lib/main.d.ts",
10
11
  "exports": {
11
12
  ".": {
12
13
  "import": "./dist/index.es.js",