diff --git a/.env b/.env index fdf93e1..f715395 100644 --- a/.env +++ b/.env @@ -11,3 +11,7 @@ SECRET_ACCESS_TOKEN=1e13d44f998dee277deae621a9012cf300b94c91 # to trust jolokia certs NODE_TLS_REJECT_UNAUTHORIZED='0' + +# logging +LOG_LEVEL='info' +ENABLE_REQUEST_LOG='false' diff --git a/package.json b/package.json index 4f33466..761f1c3 100644 --- a/package.json +++ b/package.json @@ -76,5 +76,10 @@ "yaml": "^2.4.5" }, "readme": "README.md", - "_id": "activemq-artemis-jolokia-api-server@0.1.0" + "_id": "activemq-artemis-jolokia-api-server@0.1.0", + "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e", + "dependencies": { + "express-pino-logger": "^7.0.0", + "pino": "^9.5.0" + } } diff --git a/src/api/apiutil/artemis_jolokia.ts b/src/api/apiutil/artemis_jolokia.ts index 1162938..ce9c425 100644 --- a/src/api/apiutil/artemis_jolokia.ts +++ b/src/api/apiutil/artemis_jolokia.ts @@ -616,7 +616,6 @@ export class ArtemisJolokia { this.brokerName = this.brokerName.replace(/"/g, ''); return true; } - console.log('User is not valid', this.username); return false; }; diff --git a/src/api/controllers/api_impl.ts b/src/api/controllers/api_impl.ts index efc6968..d2091fa 100644 --- a/src/api/controllers/api_impl.ts +++ b/src/api/controllers/api_impl.ts @@ -6,6 +6,7 @@ import { JolokiaReadResponse, } from '../apiutil/artemis_jolokia'; import { API_SUMMARY } from '../../utils/server'; +import { logger } from '../../utils/logger'; const BROKER = 'broker'; const ADDRESS = 'address'; @@ -40,10 +41,10 @@ export const getBrokers = (_: express.Request, res: express.Response): void => { ); }) .catch((error: any) => { - console.log(error); + logger.error(error); }); } catch (err) { - console.log(err); + logger.error(err); res.status(500).json({ status: 'error', message: 'server error: ' + JSON.stringify(err), @@ -76,10 +77,10 @@ export const getClusterConnections = ( ); }) .catch((error: any) => { - console.log(error); + logger.error(error); }); } catch (err) { - console.log(err); + logger.error(err); res.status(500).json({ status: 'error', message: 'server error: ' + JSON.stringify(err), @@ -105,11 +106,11 @@ export const readClusterConnectionAttributes = ( res.json(result); }) .catch((error: any) => { - console.log(error); + logger.error(error); res.status(500).json({ status: 'error', message: 'server error' }); }); } catch (err) { - console.log(err); + logger.error(err); res.status(500).json({ status: 'error', message: 'server error: ' + JSON.stringify(err), @@ -141,11 +142,11 @@ export const getClusterConnectionDetails = ( res.json(result); }) .catch((error: any) => { - console.log(error); + logger.error(error); res.status(500).json({ status: 'error', message: 'server error' }); }); } catch (err) { - console.log(err); + logger.error(err); res.status(500).json({ status: 'error', message: 'server error: ' + JSON.stringify(err), @@ -187,11 +188,11 @@ export const execClusterConnectionOperation = ( res.json(result); }) .catch((error: any) => { - console.log(error); + logger.error(error); res.status(500).json({ status: 'error', message: 'server error' }); }); } catch (err) { - console.log(err); + logger.error(err); res.status(500).json({ status: 'error', message: 'server error: ' + JSON.stringify(err), @@ -224,10 +225,10 @@ export const getAcceptors = ( ); }) .catch((error: any) => { - console.log(error); + logger.error(error); }); } catch (err) { - console.log(err); + logger.error(err); res.status(500).json({ status: 'error', message: 'server error: ' + JSON.stringify(err), @@ -253,11 +254,11 @@ export const readAcceptorAttributes = ( res.json(result); }) .catch((error: any) => { - console.log(error); + logger.error(error); res.status(500).json({ status: 'error', message: 'server error' }); }); } catch (err) { - console.log(err); + logger.error(err); res.status(500).json({ status: 'error', message: 'server error: ' + JSON.stringify(err), @@ -279,10 +280,10 @@ export const getBrokerComponents = ( res.json(result); }) .catch((error: any) => { - console.log(error); + logger.error(error); }); } catch (err) { - console.log(err); + logger.error(err); res.status(500).json({ status: 'error', message: 'server error: ' + JSON.stringify(err), @@ -314,10 +315,10 @@ export const getAddresses = ( ); }) .catch((error: any) => { - console.log(error); + logger.error(error); }); } catch (err) { - console.log(err); + logger.error(err); res.status(500).json({ status: 'error', message: 'server error: ' + JSON.stringify(err), @@ -343,11 +344,11 @@ export const readAddressAttributes = ( res.json(result); }) .catch((error: any) => { - console.log(error); + logger.error(error); res.status(500).json({ status: 'error', message: 'server error' }); }); } catch (err) { - console.log(err); + logger.error(err); res.status(500).json({ status: 'error', message: 'server error: ' + JSON.stringify(err), @@ -392,10 +393,10 @@ export const getQueues = ( ); }) .catch((error: any) => { - console.log(error); + logger.error(error); }); } catch (err) { - console.log(err); + logger.error(err); res.status(500).json({ status: 'error', message: 'server error: ' + JSON.stringify(err), @@ -425,11 +426,11 @@ export const readQueueAttributes = ( res.json(result); }) .catch((error: any) => { - console.log(error); + logger.error(error); res.status(500).json({ status: 'error', message: 'server error' }); }); } catch (err) { - console.log(err); + logger.error(err); res.status(500).json({ status: 'error', message: 'server error: ' + JSON.stringify(err), @@ -457,11 +458,11 @@ export const getBrokerDetails = ( res.json(result); }) .catch((error: any) => { - console.log(error); + logger.error(error); res.status(500).json({ status: 'error', message: 'server error' }); }); } catch (err) { - console.log(err); + logger.error(err); res.status(500).json({ status: 'error', message: 'server error: ' + JSON.stringify(err), @@ -513,11 +514,11 @@ export const execBrokerOperation = ( res.json(result); }) .catch((error: any) => { - console.log(error); + logger.error(error); res.status(500).json({ status: 'error', message: 'server error' }); }); } catch (err) { - console.log(err); + logger.error(err); res.status(500).json({ status: 'error', message: 'server error: ' + JSON.stringify(err), @@ -539,11 +540,11 @@ export const readBrokerAttributes = ( res.json(result); }) .catch((error: any) => { - console.log(error); + logger.error(error); res.status(500).json({ status: 'error', message: 'server error' }); }); } catch (err) { - console.log(err); + logger.error(err); res.status(500).json({ status: 'error', message: 'server error: ' + JSON.stringify(err), @@ -575,11 +576,11 @@ export const getAddressDetails = ( res.json(result); }) .catch((error: any) => { - console.log(error); + logger.error(error); res.status(500).json({ status: 'error', message: 'server error' }); }); } catch (err) { - console.log(err); + logger.error(err); res.status(500).json({ status: 'error', message: 'server error: ' + JSON.stringify(err), @@ -611,11 +612,11 @@ export const getAcceptorDetails = ( res.json(result); }) .catch((error: any) => { - console.log(error); + logger.error(error); res.status(500).json({ status: 'error', message: 'server error' }); }); } catch (err) { - console.log(err); + logger.error(err); res.status(500).json({ status: 'error', message: 'server error: ' + JSON.stringify(err), @@ -653,11 +654,11 @@ export const getQueueDetails = ( res.json(result); }) .catch((error: any) => { - console.log(error); + logger.error(error); res.status(500).json({ status: 'error', message: 'server error' }); }); } catch (err) { - console.log(err); + logger.error(err); res.status(500).json({ status: 'error', message: 'server error: ' + JSON.stringify(err), diff --git a/src/api/controllers/security.ts b/src/api/controllers/security.ts index 7c74207..3942b97 100644 --- a/src/api/controllers/security.ts +++ b/src/api/controllers/security.ts @@ -1,6 +1,7 @@ import * as express from 'express'; import jwt from 'jsonwebtoken'; import { ArtemisJolokia } from '../apiutil/artemis_jolokia'; +import { logger } from '../../utils/logger'; const securityStore = new Map(); @@ -22,7 +23,7 @@ const validateHostName = (host: string) => { let validHost: string = host; if (process.env.NODE_ENV === 'production') { if (!host.includes('wconsj')) { - console.log('invalid host', host); + logger.warn('invalid host', host); return null; } else { validHost = host; @@ -35,7 +36,7 @@ const validateScheme = (scheme: string) => { let validScheme: string = scheme; if (process.env.NODE_ENV === 'production') { if (scheme !== 'http' && scheme !== 'https') { - console.log('invalid scheme', scheme); + logger.warn('invalid scheme', scheme); return null; } else { validScheme = scheme; @@ -50,7 +51,7 @@ const validatePort = (port: string) => { if (num >= 1 && num <= 65535 && port === num.toString()) { validPort = port; } else { - console.log('invalid port', port); + logger.warn('invalid port', port); return null; } return validPort; @@ -62,7 +63,6 @@ export const login = (req: express.Request, res: express.Response) => { req.body; const validHost = validateHostName(jolokiaHost); - console.log('validHost is ', validHost); if (!validHost) { res.status(401).json({ status: 'failed', @@ -87,15 +87,6 @@ export const login = (req: express.Request, res: express.Response) => { return; } - console.log( - 'login', - 'brokerKey', - brokerName, - 'user', - userName, - 'host', - validHost, - ); const jolokia = new ArtemisJolokia( userName, password, @@ -109,7 +100,6 @@ export const login = (req: express.Request, res: express.Response) => { .validateUser() .then((result) => { if (result) { - console.log('user is valid'); const token = generateJWTToken(brokerName); securityStore.set(brokerName, jolokia); @@ -127,7 +117,7 @@ export const login = (req: express.Request, res: express.Response) => { res.end(); }) .catch((e) => { - console.log('got exception while login', e); + logger.error('got exception while login', e); res.status(500).json({ status: 'failed', message: 'Internal error', @@ -155,25 +145,20 @@ export const VerifyLogin = async ( res: express.Response, next: any, ) => { - console.log('verify login for request:', req.path); try { if (ignoreAuth(req.path)) { - console.log('ignore path', req.path); next(); } else { const authHeader = req.headers['jolokia-session-id'] as string; if (!authHeader) { - console.log('no auth'); res.sendStatus(401); } else { - console.log('verifying header', authHeader); jwt.verify( authHeader, getSecretToken(), async (err: any, decoded: any) => { if (err) { - console.log('verify failed', err); res.status(401).json({ status: 'failed', message: 'This session has expired. Please login again', diff --git a/src/app.ts b/src/app.ts index e7e7f3e..ed2dd50 100644 --- a/src/app.ts +++ b/src/app.ts @@ -3,20 +3,22 @@ import https from 'https'; import fs from 'fs'; import path from 'path'; import dotenv from 'dotenv'; +import { logger } from './utils/logger'; dotenv.config(); -console.log( - `Starting plugin ${process.env.PLUGIN_VERSION}`, - process.env.PLUGIN_NAME, +logger.info( + `Starting plugin ${process.env.PLUGIN_NAME} ${process.env.PLUGIN_VERSION}`, ); -createServer() +const isReqLogEnabled = process.env.ENABLE_REQUEST_LOG || 'false'; + +createServer(isReqLogEnabled === 'true') .then((server) => { let options = {}; if (process.env.NODE_ENV === 'production') { - console.log( + logger.info( 'setting up tls in production mode', 'cert', process.env.SERVER_CERT, @@ -34,7 +36,7 @@ createServer() throw new Error('Missing cert/key files'); } } else { - console.log('setting up tls using dev certs'); + logger.info('setting up tls using dev certs'); options = { key: fs.readFileSync(path.join(__dirname, 'config/domain.key')), cert: fs.readFileSync(path.join(__dirname, 'config/domain.crt')), @@ -42,9 +44,9 @@ createServer() } const secureServer = https.createServer(options, server); secureServer.listen(9443, () => { - console.info('Listening on https://0.0.0.0:9443'); + logger.info('Listening on https://0.0.0.0:9443'); }); }) .catch((err) => { - console.error(`Error: ${err}`); + logger.error(`Error: ${err}`); }); diff --git a/src/utils/logger.ts b/src/utils/logger.ts new file mode 100644 index 0000000..50f852b --- /dev/null +++ b/src/utils/logger.ts @@ -0,0 +1,21 @@ +import pino from 'pino'; +import expressPino from 'pino-http'; + +export const logger = pino({ + level: process.env.LOG_LEVEL || 'info', + formatters: { + level: (label) => { + return { level: label.toUpperCase() }; + }, + bindings: (bindings) => { + return {}; + }, + }, + timestamp: pino.stdTimeFunctions.isoTime, +}); + +export const logRequest = (enabled: boolean) => + expressPino({ + level: 'info', + enabled, + }); diff --git a/src/utils/server.test.ts b/src/utils/server.test.ts index dfedfa4..e78dc7b 100644 --- a/src/utils/server.test.ts +++ b/src/utils/server.test.ts @@ -19,7 +19,9 @@ const jolokiaHost = 'broker-0.test.com'; const jolokiaPort = '8161'; const startApiServer = async (): Promise => { - const result = await createServer() + process.env.API_SERVER_SECURITY_ENABLED = 'false'; + + const result = await createServer(false) .then((server) => { const options = { key: fs.readFileSync(path.join(__dirname, '../config/domain.key')), diff --git a/src/utils/server.ts b/src/utils/server.ts index ea0bc5f..14cd8a5 100644 --- a/src/utils/server.ts +++ b/src/utils/server.ts @@ -10,23 +10,24 @@ import path from 'path'; import cors from 'cors'; import * as api from '../api/controllers'; +import { logger, logRequest } from './logger'; export let API_SUMMARY: Summary; -const createServer = async (): Promise => { +const createServer = async (enableLogRequest: boolean): Promise => { const yamlSpecFile = path.join(__dirname, '../config/openapi.yml'); - console.log('parseing api.yaml', yamlSpecFile); const ymlData = fs.readFileSync(yamlSpecFile, 'utf-8'); const apiDefinition = YAML.load(ymlData) as object; - console.log('LOADED apiDef', apiDefinition); API_SUMMARY = summarise(apiDefinition); - console.log('output summary', API_SUMMARY); - console.info(API_SUMMARY); + + logger.debug(API_SUMMARY); const server = express(); // here we can intialize body/cookies parsers, connect logger, for example morgan + server.use(logRequest(enableLogRequest)); + const limiter = rateLimit({ windowMs: 1 * 60 * 1000, // 1 minute limit: 1000, // Limit each IP to 1000 requests per `window` (here, per 1 minutes). @@ -51,7 +52,7 @@ const createServer = async (): Promise => { server.use(OpenApiValidator.middleware(validatorOptions)); server.use((req, res, next) => { if (process.env.NODE_ENV === 'production') { - console.log( + logger.debug( 'in redirect handler, x-forward-proto', req.headers['x-forwarded-proto'], 'method', @@ -62,7 +63,7 @@ const createServer = async (): Promise => { req.method !== 'OPTIONS' ) { const redirUrl = 'https://' + req.headers.host + req.url; - console.log('redirecting to', redirUrl); + logger.debug('redirecting to', redirUrl); return res.redirect(redirUrl); } else { next(); @@ -75,7 +76,7 @@ const createServer = async (): Promise => { const connect = connector(api, apiDefinition, { onCreateRoute: (method: string, descriptor: any[]) => { - console.log( + logger.info( `${method}: ${descriptor[0]} : ${(descriptor[1] as any).name}`, ); }, diff --git a/yarn.lock b/yarn.lock index 08040ae..d228142 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1457,6 +1457,11 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== +atomic-sleep@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b" + integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ== + autoprefixer@^7.1.2: version "7.2.6" resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-7.2.6.tgz#256672f86f7c735da849c4f07d008abb056067dc" @@ -2313,6 +2318,16 @@ duplexer3@^0.1.4: resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.5.tgz#0b5e4d7bad5de8901ea4440624c8e1d20099217e" integrity sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA== +duplexify@^4.1.2: + version "4.1.3" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-4.1.3.tgz#a07e1c0d0a2c001158563d32592ba58bddb0236f" + integrity sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA== + dependencies: + end-of-stream "^1.4.1" + inherits "^2.0.3" + readable-stream "^3.1.1" + stream-shift "^1.0.2" + eastasianwidth@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" @@ -2362,7 +2377,7 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== -end-of-stream@^1.1.0: +end-of-stream@^1.1.0, end-of-stream@^1.4.1: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== @@ -2709,6 +2724,13 @@ express-openapi-validator@5.1.2: ono "^7.1.3" path-to-regexp "^6.2.0" +express-pino-logger@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/express-pino-logger/-/express-pino-logger-7.0.0.tgz#db81705be45c4b875e8a18a2ec6fcbd20f83bcfc" + integrity sha512-g8T6nhqq9L9AuwppymXa1rm6+A7xVUfkcEodXA+d2ILsM1uyoqSn83kpXE61v6JR2eFL8n878VyFDir1w2PuPw== + dependencies: + pino-http "^6.0.0" + express-rate-limit@^7.2.0: version "7.3.1" resolved "https://registry.yarnpkg.com/express-rate-limit/-/express-rate-limit-7.3.1.tgz#c0887ba746cdd358d17b8ab63d6eba1bae0f670b" @@ -2794,11 +2816,23 @@ fast-levenshtein@^2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== +fast-redact@^3.0.0, fast-redact@^3.1.1: + version "3.5.0" + resolved "https://registry.yarnpkg.com/fast-redact/-/fast-redact-3.5.0.tgz#e9ea02f7e57d0cd8438180083e93077e496285e4" + integrity sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A== + fast-safe-stringify@^2.0.7: version "2.1.1" resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz#c406a83b6e70d9e35ce3b30a81141df30aeba884" integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA== +fast-url-parser@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/fast-url-parser/-/fast-url-parser-1.1.3.tgz#f4af3ea9f34d8a271cf58ad2b3759f431f0b318d" + integrity sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ== + dependencies: + punycode "^1.3.2" + fastq@^1.6.0: version "1.17.1" resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47" @@ -5010,6 +5044,16 @@ object.omit@^2.0.0: for-own "^0.1.4" is-extendable "^0.1.1" +on-exit-leak-free@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/on-exit-leak-free/-/on-exit-leak-free-0.2.0.tgz#b39c9e3bf7690d890f4861558b0d7b90a442d209" + integrity sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg== + +on-exit-leak-free@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz#fed195c9ebddb7d9e4c3842f93f281ac8dadd3b8" + integrity sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA== + on-finished@2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" @@ -5326,6 +5370,80 @@ pinkie@^2.0.0: resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg== +pino-abstract-transport@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pino-abstract-transport/-/pino-abstract-transport-2.0.0.tgz#de241578406ac7b8a33ce0d77ae6e8a0b3b68a60" + integrity sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw== + dependencies: + split2 "^4.0.0" + +pino-abstract-transport@v0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/pino-abstract-transport/-/pino-abstract-transport-0.5.0.tgz#4b54348d8f73713bfd14e3dc44228739aa13d9c0" + integrity sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ== + dependencies: + duplexify "^4.1.2" + split2 "^4.0.0" + +pino-http@^6.0.0: + version "6.6.0" + resolved "https://registry.yarnpkg.com/pino-http/-/pino-http-6.6.0.tgz#d0a1deacada8c93327fdaa48f5bdc94bc43d3407" + integrity sha512-PlItaK2MLpoIMLEcClhfb1VQk/o6fKppINl5s6sPE/4rvufkdO3kCSs/92EwrBsB1yssRCQqDV+w1xpYuPVnjg== + dependencies: + fast-url-parser "^1.1.3" + get-caller-file "^2.0.5" + pino "^7.5.0" + pino-std-serializers "^5.0.0" + +pino-std-serializers@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/pino-std-serializers/-/pino-std-serializers-4.0.0.tgz#1791ccd2539c091ae49ce9993205e2cd5dbba1e2" + integrity sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q== + +pino-std-serializers@^5.0.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/pino-std-serializers/-/pino-std-serializers-5.6.0.tgz#31b141155d6520967c5ec72944d08fb45c490fd3" + integrity sha512-VdUXCw8gO+xhir7sFuoYSjTnzB+TMDGxhAC/ph3YS3sdHnXNdsK0wMtADNUltfeGkn2KDxEM21fnjF3RwXyC8A== + +pino-std-serializers@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/pino-std-serializers/-/pino-std-serializers-7.0.0.tgz#7c625038b13718dbbd84ab446bd673dc52259e3b" + integrity sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA== + +pino@^7.5.0: + version "7.11.0" + resolved "https://registry.yarnpkg.com/pino/-/pino-7.11.0.tgz#0f0ea5c4683dc91388081d44bff10c83125066f6" + integrity sha512-dMACeu63HtRLmCG8VKdy4cShCPKaYDR4youZqoSWLxl5Gu99HUw8bw75thbPv9Nip+H+QYX8o3ZJbTdVZZ2TVg== + dependencies: + atomic-sleep "^1.0.0" + fast-redact "^3.0.0" + on-exit-leak-free "^0.2.0" + pino-abstract-transport v0.5.0 + pino-std-serializers "^4.0.0" + process-warning "^1.0.0" + quick-format-unescaped "^4.0.3" + real-require "^0.1.0" + safe-stable-stringify "^2.1.0" + sonic-boom "^2.2.1" + thread-stream "^0.15.1" + +pino@^9.5.0: + version "9.5.0" + resolved "https://registry.yarnpkg.com/pino/-/pino-9.5.0.tgz#a7ef0fea868d22d52d8a4ce46e6e03c5dc46fdd6" + integrity sha512-xSEmD4pLnV54t0NOUN16yCl7RIB1c5UUOse5HSyEXtBp+FgFQyPeDutc+Q2ZO7/22vImV7VfEjH/1zV2QuqvYw== + dependencies: + atomic-sleep "^1.0.0" + fast-redact "^3.1.1" + on-exit-leak-free "^2.1.0" + pino-abstract-transport "^2.0.0" + pino-std-serializers "^7.0.0" + process-warning "^4.0.0" + quick-format-unescaped "^4.0.3" + real-require "^0.2.0" + safe-stable-stringify "^2.3.1" + sonic-boom "^4.0.1" + thread-stream "^3.0.0" + pirates@^4.0.4: version "4.0.6" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" @@ -5519,6 +5637,16 @@ process-nextick-args@~2.0.0: resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== +process-warning@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/process-warning/-/process-warning-1.0.0.tgz#980a0b25dc38cd6034181be4b7726d89066b4616" + integrity sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q== + +process-warning@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/process-warning/-/process-warning-4.0.0.tgz#581e3a7a1fb456c5f4fd239f76bce75897682d5a" + integrity sha512-/MyYDxttz7DfGMMHiysAsFE4qF+pQYAA8ziO/3NcRVrQ5fSk+Mns4QZA/oRPFzvcqNoVJXQNWNAsdwBXLUkQKw== + prompts@^2.0.1: version "2.4.2" resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" @@ -5558,6 +5686,11 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" +punycode@^1.3.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ== + punycode@^2.1.0, punycode@^2.1.1: version "2.3.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" @@ -5580,6 +5713,11 @@ queue-microtask@^1.2.2: resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== +quick-format-unescaped@^4.0.3: + version "4.0.4" + resolved "https://registry.yarnpkg.com/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz#93ef6dd8d3453cbc7970dd614fad4c5954d6b5a7" + integrity sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg== + quick-lru@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8" @@ -5687,6 +5825,16 @@ readable-stream@^3.1.1: string_decoder "^1.1.1" util-deprecate "^1.0.1" +real-require@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/real-require/-/real-require-0.1.0.tgz#736ac214caa20632847b7ca8c1056a0767df9381" + integrity sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg== + +real-require@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/real-require/-/real-require-0.2.0.tgz#209632dea1810be2ae063a6ac084fee7e33fba78" + integrity sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg== + redent@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" @@ -5921,6 +6069,11 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== +safe-stable-stringify@^2.1.0, safe-stable-stringify@^2.3.1: + version "2.5.0" + resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz#4ca2f8e385f2831c432a719b108a3bf7af42a1dd" + integrity sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA== + "safer-buffer@>= 2.1.2 < 3": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" @@ -6163,6 +6316,20 @@ slice-ansi@^5.0.0: ansi-styles "^6.0.0" is-fullwidth-code-point "^4.0.0" +sonic-boom@^2.2.1: + version "2.8.0" + resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-2.8.0.tgz#c1def62a77425090e6ad7516aad8eb402e047611" + integrity sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg== + dependencies: + atomic-sleep "^1.0.0" + +sonic-boom@^4.0.1: + version "4.2.0" + resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-4.2.0.tgz#e59a525f831210fa4ef1896428338641ac1c124d" + integrity sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww== + dependencies: + atomic-sleep "^1.0.0" + sort-object-keys@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/sort-object-keys/-/sort-object-keys-1.1.3.tgz#bff833fe85cab147b34742e45863453c1e190b45" @@ -6236,6 +6403,11 @@ specificity@^0.3.1: resolved "https://registry.yarnpkg.com/specificity/-/specificity-0.3.2.tgz#99e6511eceef0f8d9b57924937aac2cb13d13c42" integrity sha512-Nc/QN/A425Qog7j9aHmwOrlwX2e7pNI47ciwxwy4jOlvbbMHkNNJchit+FX+UjF3IAdiaaV5BKeWuDUnws6G1A== +split2@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4" + integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg== + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -6258,6 +6430,11 @@ statuses@2.0.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== +stream-shift@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.3.tgz#85b8fab4d71010fc3ba8772e8046cc49b8a3864b" + integrity sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ== + streamsearch@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" @@ -6637,6 +6814,20 @@ text-table@^0.2.0: resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== +thread-stream@^0.15.1: + version "0.15.2" + resolved "https://registry.yarnpkg.com/thread-stream/-/thread-stream-0.15.2.tgz#fb95ad87d2f1e28f07116eb23d85aba3bc0425f4" + integrity sha512-UkEhKIg2pD+fjkHQKyJO3yoIvAP3N6RlNFt2dUhcS1FGvCD1cQa1M/PGknCLFIyZdtJOWQjejp7bdNqmN7zwdA== + dependencies: + real-require "^0.1.0" + +thread-stream@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/thread-stream/-/thread-stream-3.1.0.tgz#4b2ef252a7c215064507d4ef70c05a5e2d34c4f1" + integrity sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A== + dependencies: + real-require "^0.2.0" + throat@^6.0.1: version "6.0.2" resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.2.tgz#51a3fbb5e11ae72e2cf74861ed5c8020f89f29fe"