diff --git a/caracal.js b/caracal.js index 03f47a8..36b5572 100644 --- a/caracal.js +++ b/caracal.js @@ -21,6 +21,10 @@ const sanitizeBody = require('./handlers/sanitizeHandler.js'); const DataSet = require('./handlers/datasetHandler.js'); const Model = require('./handlers/modelTrainer.js'); const DataTransformationHandler = require('./handlers/dataTransformationHandler.js'); + +// services +const {logger} = require('./service/logger/winston'); + // TODO validation of data var WORKERS = process.env.NUM_THREADS || 4; @@ -139,12 +143,12 @@ for (let i in routeConfig) { if (Object.prototype.hasOwnProperty.call(routeConfig, i)) { let rule = routeConfig[i]; if (!rule.method) { - console.error('rule number '+ i +' has no "method"'); + logger.error('rule number '+ i +' has no "method"'); process.exit(1); } if (rule.method == 'static') { if (!rule.use) { - console.error('rule number '+ i +' is static and has no "use"'); + logger.error('rule number '+ i +' is static and has no "use"'); process.exit(1); } app.use(express.static(rule.use)); @@ -153,15 +157,15 @@ for (let i in routeConfig) { if (Object.prototype.hasOwnProperty.call(rule.handlers, j)) { let handler = rule.handlers[j]; if (!rule.route) { - console.error('rule number '+ i +' has no "route"'); + logger.error('rule number '+ i +' has no "route"'); process.exit(1); } if (!handler.function) { - console.error('rule number '+ i +' handler ' + j + ' has no "function"'); + logger.error('rule number '+ i +' handler ' + j + ' has no "function"'); process.exit(1); } if (! HANDLERS.hasOwnProperty(handler.function)) { - console.error('handler named "'+ handler.function + '" not found (rule '+ i +' handler ' + j + ')'); + logger.error('handler named "'+ handler.function + '" not found (rule '+ i +' handler ' + j + ')'); process.exit(1); } let args = handler.args || []; @@ -187,9 +191,9 @@ app.use(function(err, req, res, next) { // wrap strings in a json if (typeof err === 'string' || err instanceof String) { err = {'error': err}; - console.error(err); + logger.error(err); } else { - console.error(err.error || err.message || err.toString()); + logger.error(err.error || err.message || err.toString()); } res.status(statusCode).json(err); }); @@ -202,17 +206,17 @@ var startApp = function(app) { var sslPkPath = "./ssl/privatekey.pem"; var sslCertPath = "./ssl/certificate.pem"; if (fs.existsSync(sslPkPath) && fs.existsSync(sslCertPath)) { - console.info("Starting in HTTPS Mode mode"); + logger.info("Starting in HTTPS Mode mode"); httpsOptions.key = fs.readFileSync(sslPkPath, 'utf8'); httpsOptions.cert = fs.readFileSync(sslCertPath, 'utf8'); } } catch (err) { - console.error(err); + logger.error(err); } if (httpsOptions.key && httpsOptions.cert) { - https.createServer(httpsOptions, app).listen(PORT, () => console.log('listening HTTPS on ' + PORT)); + https.createServer(httpsOptions, app).listen(PORT, () => logger.info('listening HTTPS on ' + PORT)); } else { - app.listen(PORT, () => console.log('listening on ' + PORT)); + app.listen(PORT, () => logger.info('listening on ' + PORT)); } }; }; diff --git a/handlers/authHandlers.js b/handlers/authHandlers.js index 0db87ae..1c80bf0 100644 --- a/handlers/authHandlers.js +++ b/handlers/authHandlers.js @@ -4,6 +4,7 @@ const jwksClient = require('jwks-rsa'); var atob = require('atob'); var fs = require('fs'); var filterFunction = require('./filterFunction.js'); +const {logger} = require('../service/logger/winston'); const {execSync} = require('child_process'); const preCommand = "openssl req -subj "; @@ -24,7 +25,7 @@ if (!fs.existsSync('./keys/key') && !fs.existsSync('./keys/key.pub') && GENERATE try { execSync(`${preCommand}'/CN=www.camicroscope.com/O=caMicroscope Local Instance Key./C=US'${postCommand}`); } catch (err) { - console.log({err: err}); + logger.info({err: err}); } } @@ -35,13 +36,13 @@ try { } else { if (DISABLE_SEC || ENABLE_SECURITY_AT && Date.parse(ENABLE_SECURITY_AT) > Date.now()) { PRIKEY = ''; - console.warn('prikey null since DISABLE_SEC and no prikey provided'); + logger.warn('prikey null since DISABLE_SEC and no prikey provided'); } else { - console.error('prikey does not exist'); + logger.error('prikey does not exist'); } } } catch (err) { - console.error(err); + logger.error(err); } try { @@ -51,13 +52,13 @@ try { } else { if (DISABLE_SEC || ENABLE_SECURITY_AT && Date.parse(ENABLE_SECURITY_AT) > Date.now()) { PUBKEY = ''; - console.warn('pubkey null since DISABLE_SEC and no prikey provided'); + logger.warn('pubkey null since DISABLE_SEC and no prikey provided'); } else { - console.error('pubkey does not exist'); + logger.error('pubkey does not exist'); } } } catch (err) { - console.error(err); + logger.error(err); } if (DISABLE_SEC && !JWK_URL) { @@ -69,7 +70,7 @@ if (DISABLE_SEC && !JWK_URL) { jwksUri: JWK_URL, }); } else { - console.error('need JWKS URL (JWK_URL)'); + logger.error('need JWKS URL (JWK_URL)'); process.exit(1); } @@ -104,9 +105,9 @@ function jwkTokenTrade(jwksClient, signKey, userFunction) { res.status(401).send('{"err":"no token found"}'); } jwksClient.getSigningKey(getJwtKid(THISTOKEN), (err, key) => { - // console.log(key); + // logger.info(key); if (err) { - console.error(err); + logger.error(err); res.status(401).send({ 'err': err, }); @@ -131,7 +132,7 @@ function tokenTrade(checkKey, signKey, userFunction) { } jwt.verify(THISTOKEN, checkKey, jwtOptions, function(err, token) { if (err) { - console.error(err); + logger.error(err); res.status(401).send({ 'err': err, }); @@ -143,7 +144,7 @@ function tokenTrade(checkKey, signKey, userFunction) { }); } else { userFunction(token).then((x) => { - // console.log(x); + // logger.info(x); if (x === false) { res.status(401).send({ 'err': 'User Unauthorized', @@ -161,7 +162,7 @@ function tokenTrade(checkKey, signKey, userFunction) { }); } }).catch((e) => { - console.log(e); + logger.info(e); res.status(401).send(e); }); } @@ -177,7 +178,7 @@ function loginHandler(checkKey) { try { token = jwt.decode(getToken(req)) || {}; } catch (e) { - console.warn(e); + logger.warn(e); } req.tokenInfo = token; req.userType = token.userType || DEFAULT_USER_TYPE || 'Null'; @@ -193,7 +194,7 @@ function loginHandler(checkKey) { } jwt.verify(getToken(req), checkKey, jwtOptions, function(err, token) { if (err) { - console.error(err); + logger.error(err); res.status(401).send({ 'err': err, }); diff --git a/handlers/dataHandlers.js b/handlers/dataHandlers.js index 7852339..c2dfbde 100644 --- a/handlers/dataHandlers.js +++ b/handlers/dataHandlers.js @@ -2,6 +2,7 @@ var mongo = require('mongodb'); var MONGO_URI = process.env.MONGO_URI || 'mongodb://localhost'; var DISABLE_SEC = (process.env.DISABLE_SEC === 'true') || false; +const {logger} = require('../service/logger/winston'); function mongoFind(database, collection, query) { @@ -54,7 +55,7 @@ function mongoDistinct(database, collection, upon, query) { } }); } catch (error) { - console.error(error); + logger.error(error); rej(error); } }); @@ -82,7 +83,7 @@ function mongoAdd(database, collection, data) { } }); } catch (error) { - console.error(error); + logger.error(error); rej(error); } }); @@ -109,7 +110,7 @@ function mongoDelete(database, collection, query) { }); } } catch (error) { - console.error(error); + logger.error(error); rej(error); } }); @@ -139,7 +140,7 @@ function mongoAggregate(database, collection, pipeline) { }); } } catch (error) { - console.error(error); + logger.error(error); rej(error); } }); @@ -159,7 +160,7 @@ function mongoUpdate(database, collection, query, newVals) { } dbo.collection(collection).updateOne(query, newVals, function(err, result) { if (err) { - console.log(err); + logger.info(err); rej(err); } delete result.connection; diff --git a/handlers/dataTransformationHandler.js b/handlers/dataTransformationHandler.js index 3458777..d476b0c 100644 --- a/handlers/dataTransformationHandler.js +++ b/handlers/dataTransformationHandler.js @@ -1,6 +1,8 @@ const client = require("mongodb").MongoClient; const fs = require("fs"); +const {logger} = require('../service/logger/winston'); + class DataTransformationHandler { constructor(url, path) { this.url = url; @@ -14,7 +16,7 @@ class DataTransformationHandler { } startHandler() { - console.log("||-- Start --||"); + logger.info("||-- Start --||"); this.counter = 0; this.max = 300; this.id = 1; @@ -29,7 +31,7 @@ class DataTransformationHandler { config = JSON.parse(rawdata); } catch (err) { if (err.code == "ENOENT") { - console.log(`'${this.filePath}' File Fot Found!`); + logger.info(`'${this.filePath}' File Fot Found!`); } else { throw err; } @@ -54,8 +56,8 @@ class DataTransformationHandler { collection.find(query).toArray((err, rs) => { if (err) { this.isProcessing = false; - console.log(`||-- The 'Preset Labels' Document Upgrade Is Failed --||`); - console.log(err); + logger.info(`||-- The 'Preset Labels' Document Upgrade Is Failed --||`); + logger.info(err); dbc.close(); this.cleanHandler(); return; @@ -68,8 +70,8 @@ class DataTransformationHandler { collection.insertOne(defaultData, (err, result) => { if (err) { this.isProcessing = false; - console.log(`||-- The 'Preset Labels' Document Upgrade Is Failed --||`); - console.log(err); + logger.info(`||-- The 'Preset Labels' Document Upgrade Is Failed --||`); + logger.info(err); dbc.close(); this.cleanHandler(); return; @@ -95,8 +97,8 @@ class DataTransformationHandler { collection.deleteOne(query, (err, result) => { if (err) { this.isProcessing = false; - console.log(`||-- The 'Preset Labels' Document Upgrade Is Failed --||`); - console.log(err); + logger.info(`||-- The 'Preset Labels' Document Upgrade Is Failed --||`); + logger.info(err); dbc.close(); this.cleanHandler(); return; @@ -104,14 +106,14 @@ class DataTransformationHandler { collection.insertOne(config, (err, result) => { if (err) { this.isProcessing = false; - console.log(`||-- The 'Preset Labels' Document Upgrade Is Failed --||`); - console.log(err); + logger.info(`||-- The 'Preset Labels' Document Upgrade Is Failed --||`); + logger.info(err); dbc.close(); this.cleanHandler(); return; } this.isProcessing = false; - console.log(`||-- The Document At The 'configuration' Collection Has Been Upgraded To Version 1.0.0 --||`); + logger.info(`||-- The Document At The 'configuration' Collection Has Been Upgraded To Version 1.0.0 --||`); dbc.close(); this.cleanHandler(); }); @@ -119,8 +121,8 @@ class DataTransformationHandler { } }); }).catch((err) => { - console.log(`||-- The 'Preset Labels' Document Upgrade Is Failed --||`); - console.log(err.message); + logger.info(`||-- The 'Preset Labels' Document Upgrade Is Failed --||`); + logger.info(err.message); this.isProcessing = false; if (this.max == this.counter) { this.cleanHandler(); @@ -144,7 +146,7 @@ class DataTransformationHandler { } cleanHandler() { - console.log("||-- Done --||"); + logger.info("||-- Done --||"); this.counter = 0; this.max = 300; this.id = 1; diff --git a/handlers/datasetHandler.js b/handlers/datasetHandler.js index 726332e..f98d01d 100644 --- a/handlers/datasetHandler.js +++ b/handlers/datasetHandler.js @@ -10,6 +10,8 @@ const crypto = require("crypto"); const AdmZip = require('adm-zip'); const path = require('path'); +const {logger} = require('../service/logger/winston'); + let LABELS_PATH = null; let IMAGES_SPRITE_PATH = null; @@ -32,7 +34,7 @@ class Data { async load() { let This = this; const imgRequest = new Promise((resolve) => { - // console.log(this.IMAGES_SPRITE_PATH); + // logger.info(this.IMAGES_SPRITE_PATH); inkjet.decode(fs.readFileSync(this.IMAGES_SPRITE_PATH), function(err, decoded) { const pixels = Float32Array.from(decoded.data).map((pixel) => { return pixel / 255; @@ -126,7 +128,7 @@ class Data { function getDataset() { return function(req, res) { let data = JSON.parse(req.body); - // console.log(req.body.ar); + // logger.info(req.body.ar); let userFolder = crypto.randomBytes(20).toString('hex'); if (!fs.existsSync('dataset')) { fs.mkdirSync('dataset/'); @@ -155,7 +157,7 @@ function deleteData() { if (err) { throw err; } - console.log(`Temp folder deleted!`); + logger.info(`Temp folder deleted!`); }); res.json({status: 'Temp folder deleted!'}); }; diff --git a/handlers/iipHandler.js b/handlers/iipHandler.js index d7cacd5..d3a7c45 100644 --- a/handlers/iipHandler.js +++ b/handlers/iipHandler.js @@ -1,6 +1,7 @@ var proxy = require('http-proxy-middleware'); var IIP_PATH = process.env.IIP_PATH || 'http://ca-iip/'; +const {logger} = require('../service/logger/winston'); iipHandler = function(req, res, next) { if (req.query) { @@ -22,7 +23,7 @@ iipHandler = function(req, res, next) { proxy({ secure: false, onError(err, req, res) { - console.log(err); + logger.error(err); err.statusCode = 500; next(err); }, diff --git a/handlers/modelTrainer.js b/handlers/modelTrainer.js index 123b8a2..6bc1185 100644 --- a/handlers/modelTrainer.js +++ b/handlers/modelTrainer.js @@ -6,12 +6,13 @@ const tf = require('@tensorflow/tfjs-node'); const Data = require('./datasetHandler.js'); const AdmZip = require('adm-zip'); +const {logger} = require('../service/logger/winston'); let Layers = []; let Params = {}; function getModel(Layers, Params, res) { - // console.log(Params) + // logger.info(Params) let model; try { model = tf.sequential({ @@ -32,6 +33,7 @@ function getModel(Layers, Params, res) { }); } } catch (error) { + logger.error(error); res.status(400).json({message: error.message}); // res.send(error); } @@ -66,7 +68,7 @@ async function train(model, data, Params) { validationData: [testXs, testYs], epochs: Number(Params.epochs), shuffle: Params.shuffle, - // callbacks: console.log(1), + // callbacks: logger.info(1), }).then(() => { tf.dispose([trainXs, trainYs, testXs, testYs, d2, d1]); }); @@ -89,7 +91,7 @@ async function run(Layers, Params, res, userFolder) { model.summary(); trained = await train(model, data, Params); - console.log('TRAINING DONE'); + logger.info('TRAINING DONE'); await model.save('file://./dataset/' + userFolder + '/'); @@ -103,7 +105,7 @@ async function run(Layers, Params, res, userFolder) { res.json({status: 'done'}); } catch (error) { - console.log(error); + logger.error(error); tf.dispose([model, trained, data.xs, data.labels]); tf.disposeVariables(); res.status(400).json({message: error.message}); @@ -153,10 +155,10 @@ function makeLayers(layers, res, userFolder) { delete layers[i].layer; Layers.splice(Layers.length - 1, 0, tf.layers.globalMaxPooling2d(layers[i])); } - // console.log(layers[i]); + // logger.info(layers[i]); } } catch (error) { - console.log(error); + logger.error(error); res.status(400).json({message: error.message}); return; } diff --git a/handlers/proxyHandler.js b/handlers/proxyHandler.js index 22a5afa..2ddcd03 100644 --- a/handlers/proxyHandler.js +++ b/handlers/proxyHandler.js @@ -1,4 +1,5 @@ var proxy = require('http-proxy-middleware'); +const {logger} = require('../service/logger/winston'); proxyHandler = function(target, n) { n = n || 2; @@ -6,15 +7,15 @@ proxyHandler = function(target, n) { proxy({ secure: false, onError(err, req, res) { - console.log(err); + logger.error(err); err.statusCode = 500; next(err); }, changeOrigin: true, target: target, pathRewrite: function(path, req) { - console.log(target); - console.log(path); + logger.info(target); + logger.info(path); // NOTE -- this may need to change if the original url has more subdirs or so added var splitPath = path.split('/'); return '/' + splitPath.slice(n, splitPath.length).join('/'); diff --git a/package-lock.json b/package-lock.json index 96275b5..f8edb92 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,7 +19,8 @@ "jsonwebtoken": "^8.5.1", "jwks-rsa": "^1.12.1", "mongodb": "^3.3.5", - "throng": "^4.0.0" + "throng": "^4.0.0", + "winston": "^3.3.3" }, "devDependencies": { "chai": "^4.2.0", @@ -56,6 +57,16 @@ "js-tokens": "^4.0.0" } }, + "node_modules/@dabh/diagnostics": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.2.tgz", + "integrity": "sha512-+A1YivoVDNNVCdfozHSR8v/jyuuLTMXwjWuxPFlFlUapXoGc+Gj9mDlTDDfrwl7rXCl2tNZ0kE8sIBO6YOn96Q==", + "dependencies": { + "colorspace": "1.1.x", + "enabled": "2.0.x", + "kuler": "^2.0.0" + } + }, "node_modules/@tensorflow/tfjs": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/@tensorflow/tfjs/-/tfjs-2.7.0.tgz", @@ -530,6 +541,11 @@ "node": ">=4" } }, + "node_modules/async": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", + "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==" + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -754,11 +770,19 @@ "node": ">=0.10.0" } }, + "node_modules/color": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/color/-/color-3.0.0.tgz", + "integrity": "sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w==", + "dependencies": { + "color-convert": "^1.9.1", + "color-string": "^1.5.2" + } + }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "dependencies": { "color-name": "1.1.3" } @@ -766,8 +790,33 @@ "node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "node_modules/color-string": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.5.tgz", + "integrity": "sha512-jgIoum0OfQfq9Whcfc2z/VhCNcmQjWbey6qBX0vqt7YICflUmBCh9E9CiQD5GSJ+Uehixm3NUwHVhqUAWRivZg==", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/colorspace": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.2.tgz", + "integrity": "sha512-vt+OoIP2d76xLhjwbBaucYlNSpPsrJWPlBTtwCpQKIu6/CSMutyzX93O/Do0qzpH3YoHEes8YEFXyZ797rEhzQ==", + "dependencies": { + "color": "3.0.x", + "text-hex": "1.0.x" + } }, "node_modules/combined-stream": { "version": "1.0.8", @@ -990,6 +1039,11 @@ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, + "node_modules/enabled": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", + "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" + }, "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -1329,6 +1383,16 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, + "node_modules/fast-safe-stringify": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", + "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==" + }, + "node_modules/fecha": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.0.tgz", + "integrity": "sha512-aN3pcx/DSmtyoovUudctc8+6Hl4T+hI9GBBHLjA76jdZl7+b1sgh5g4k+u/GL3dTy1/pnYzKp69FpJ0OicE3Wg==" + }, "node_modules/figures": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", @@ -1401,6 +1465,11 @@ "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", "dev": true }, + "node_modules/fn.name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", + "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" + }, "node_modules/follow-redirects": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.11.0.tgz", @@ -1942,6 +2011,11 @@ "node": ">= 0.10" } }, + "node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -1995,6 +2069,14 @@ "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", "dev": true }, + "node_modules/is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "engines": { + "node": ">=8" + } + }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -2143,6 +2225,11 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/kuler": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", + "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" + }, "node_modules/levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", @@ -2211,6 +2298,23 @@ "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" }, + "node_modules/logform": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.2.0.tgz", + "integrity": "sha512-N0qPlqfypFx7UHNn4B3lzS/b0uLqt2hmuoa+PpuXNYgozdJYAyauF5Ky0BWVjrxDlMWiT3qN4zPq3vVAfZy7Yg==", + "dependencies": { + "colors": "^1.2.1", + "fast-safe-stringify": "^2.0.4", + "fecha": "^4.2.0", + "ms": "^2.1.1", + "triple-beam": "^1.3.0" + } + }, + "node_modules/logform/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, "node_modules/lru-cache": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz", @@ -2544,6 +2648,14 @@ "wrappy": "1" } }, + "node_modules/one-time": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", + "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", + "dependencies": { + "fn.name": "1.x.x" + } + }, "node_modules/onetime": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", @@ -3004,6 +3116,14 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, "node_modules/slice-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", @@ -3041,6 +3161,14 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, + "node_modules/stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", + "engines": { + "node": "*" + } + }, "node_modules/statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", @@ -3225,6 +3353,11 @@ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, + "node_modules/text-hex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", + "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -3279,6 +3412,11 @@ "node": ">=0.6" } }, + "node_modules/triple-beam": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", + "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" + }, "node_modules/tslib": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz", @@ -3435,6 +3573,50 @@ "node": ">=4" } }, + "node_modules/winston": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.3.3.tgz", + "integrity": "sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw==", + "dependencies": { + "@dabh/diagnostics": "^2.0.2", + "async": "^3.1.0", + "is-stream": "^2.0.0", + "logform": "^2.2.0", + "one-time": "^1.0.0", + "readable-stream": "^3.4.0", + "stack-trace": "0.0.x", + "triple-beam": "^1.3.0", + "winston-transport": "^4.4.0" + }, + "engines": { + "node": ">= 6.4.0" + } + }, + "node_modules/winston-transport": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.4.0.tgz", + "integrity": "sha512-Lc7/p3GtqtqPBYYtS6KCN3c77/2QCev51DvcJKbkFPQNoj1sinkGwLGFDxkXY9J6p9+EPnYs+D90uwbnaiURTw==", + "dependencies": { + "readable-stream": "^2.3.7", + "triple-beam": "^1.2.0" + }, + "engines": { + "node": ">= 6.4.0" + } + }, + "node_modules/winston/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -3578,6 +3760,16 @@ "js-tokens": "^4.0.0" } }, + "@dabh/diagnostics": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.2.tgz", + "integrity": "sha512-+A1YivoVDNNVCdfozHSR8v/jyuuLTMXwjWuxPFlFlUapXoGc+Gj9mDlTDDfrwl7rXCl2tNZ0kE8sIBO6YOn96Q==", + "requires": { + "colorspace": "1.1.x", + "enabled": "2.0.x", + "kuler": "^2.0.0" + } + }, "@tensorflow/tfjs": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/@tensorflow/tfjs/-/tfjs-2.7.0.tgz", @@ -3989,6 +4181,11 @@ "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", "dev": true }, + "async": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", + "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==" + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -4173,11 +4370,19 @@ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" }, + "color": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/color/-/color-3.0.0.tgz", + "integrity": "sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w==", + "requires": { + "color-convert": "^1.9.1", + "color-string": "^1.5.2" + } + }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "requires": { "color-name": "1.1.3" } @@ -4185,8 +4390,30 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "color-string": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.5.tgz", + "integrity": "sha512-jgIoum0OfQfq9Whcfc2z/VhCNcmQjWbey6qBX0vqt7YICflUmBCh9E9CiQD5GSJ+Uehixm3NUwHVhqUAWRivZg==", + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" + }, + "colorspace": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.2.tgz", + "integrity": "sha512-vt+OoIP2d76xLhjwbBaucYlNSpPsrJWPlBTtwCpQKIu6/CSMutyzX93O/Do0qzpH3YoHEes8YEFXyZ797rEhzQ==", + "requires": { + "color": "3.0.x", + "text-hex": "1.0.x" + } }, "combined-stream": { "version": "1.0.8", @@ -4364,6 +4591,11 @@ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, + "enabled": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", + "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" + }, "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -4643,6 +4875,16 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, + "fast-safe-stringify": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", + "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==" + }, + "fecha": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.0.tgz", + "integrity": "sha512-aN3pcx/DSmtyoovUudctc8+6Hl4T+hI9GBBHLjA76jdZl7+b1sgh5g4k+u/GL3dTy1/pnYzKp69FpJ0OicE3Wg==" + }, "figures": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", @@ -4700,6 +4942,11 @@ "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", "dev": true }, + "fn.name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", + "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" + }, "follow-redirects": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.11.0.tgz", @@ -5142,6 +5389,11 @@ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" }, + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -5180,6 +5432,11 @@ "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", "dev": true }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" + }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -5318,6 +5575,11 @@ "safe-buffer": "^5.0.1" } }, + "kuler": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", + "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" + }, "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", @@ -5383,6 +5645,25 @@ "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" }, + "logform": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.2.0.tgz", + "integrity": "sha512-N0qPlqfypFx7UHNn4B3lzS/b0uLqt2hmuoa+PpuXNYgozdJYAyauF5Ky0BWVjrxDlMWiT3qN4zPq3vVAfZy7Yg==", + "requires": { + "colors": "^1.2.1", + "fast-safe-stringify": "^2.0.4", + "fecha": "^4.2.0", + "ms": "^2.1.1", + "triple-beam": "^1.3.0" + }, + "dependencies": { + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + } + } + }, "lru-cache": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz", @@ -5657,6 +5938,14 @@ "wrappy": "1" } }, + "one-time": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", + "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", + "requires": { + "fn.name": "1.x.x" + } + }, "onetime": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", @@ -6022,6 +6311,14 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "requires": { + "is-arrayish": "^0.3.1" + } + }, "slice-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", @@ -6055,6 +6352,11 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, + "stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" + }, "statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", @@ -6213,6 +6515,11 @@ } } }, + "text-hex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", + "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -6255,6 +6562,11 @@ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" }, + "triple-beam": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", + "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" + }, "tslib": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz", @@ -6377,6 +6689,43 @@ } } }, + "winston": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.3.3.tgz", + "integrity": "sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw==", + "requires": { + "@dabh/diagnostics": "^2.0.2", + "async": "^3.1.0", + "is-stream": "^2.0.0", + "logform": "^2.2.0", + "one-time": "^1.0.0", + "readable-stream": "^3.4.0", + "stack-trace": "0.0.x", + "triple-beam": "^1.3.0", + "winston-transport": "^4.4.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "winston-transport": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.4.0.tgz", + "integrity": "sha512-Lc7/p3GtqtqPBYYtS6KCN3c77/2QCev51DvcJKbkFPQNoj1sinkGwLGFDxkXY9J6p9+EPnYs+D90uwbnaiURTw==", + "requires": { + "readable-stream": "^2.3.7", + "triple-beam": "^1.2.0" + } + }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", diff --git a/package.json b/package.json index efd2969..275d6e1 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,8 @@ "jsonwebtoken": "^8.5.1", "jwks-rsa": "^1.12.1", "mongodb": "^3.3.5", - "throng": "^4.0.0" + "throng": "^4.0.0", + "winston": "^3.3.3" }, "devDependencies": { "chai": "^4.2.0", diff --git a/service/logger/winston.js b/service/logger/winston.js new file mode 100644 index 0000000..347aff5 --- /dev/null +++ b/service/logger/winston.js @@ -0,0 +1,49 @@ +const winston = require("winston"); + +const logger = winston.createLogger({ + level: "info", + format: winston.format.combine( + winston.format.simple(), + winston.format.colorize(), + winston.format.prettyPrint(), + winston.format.errors({stack: true}), + ), + + transports: [ + new winston.transports.File({ + filename: "error.log", + level: "error", + format: winston.format.combine( + winston.format.timestamp({ + format: "YYYY-MM-DD HH:mm:ss", + }), + winston.format.simple(), + winston.format.json(), + winston.format.prettyPrint(), + winston.format.errors({stack: true}), + ), + }), + new winston.transports.File({ + filename: "combined.log", + format: winston.format.combine( + winston.format.timestamp({ + format: "YYYY-MM-DD HH:mm:ss", + }), + winston.format.simple(), + winston.format.json(), + winston.format.prettyPrint(), + winston.format.errors({stack: true}), + ), + }), + ], +}); + +if (process.env.node_env !== "production") { + logger.add( + new winston.transports.Console({ + format: winston.format.simple(), + }), + ); +} + +module.exports = {logger}; \ No newline at end of file