Updated the files.

This commit is contained in:
Batuhan Berk Başoğlu 2024-02-08 19:38:41 -05:00
parent 1553e6b971
commit 753967d4f5
23418 changed files with 3784666 additions and 0 deletions

477
my-app/node_modules/log4js/CHANGELOG.md generated vendored Executable file
View file

@ -0,0 +1,477 @@
# log4js-node Changelog
## [6.9.1](https://github.com/log4js-node/log4js-node/milestone/94)
- [fix(7922e82): regex for stacktrace](https://github.com/log4js-node/log4js-node/pull/1378) - thanks [@lamweili](https://github.com/lamweili)
- addresses [#1377](https://github.com/log4js-node/log4js-node/issues/1377) which has a regression since [6.8.0](https://github.com/log4js-node/log4js-node/milestone/92) from [#1363](https://github.com/log4js-node/log4js-node/pull/1363) at commit [7922e82](https://github.com/log4js-node/log4js-node/commit/7922e8257806811666c1d4cf6774b4426276ea16)
## [6.9.0](https://github.com/log4js-node/log4js-node/milestone/93)
- [feat: support for idempotent logging on browser](https://github.com/log4js-node/log4js-node/pull/1374) - thanks [@aellerton](https://github.com/aellerton)
- addresses [#968](https://github.com/log4js-node/log4js-node/issues/968), [#1270](https://github.com/log4js-node/log4js-node/issues/1270), [#1288](https://github.com/log4js-node/log4js-node/issues/1288), [#1372](https://github.com/log4js-node/log4js-node/issues/1372)
- [docs: added that `log4js.getLogger()` may call `log4js.configure()`](https://github.com/log4js-node/log4js-node/pull/1375) - thanks [@lamweili](https://github.com/lamweili)
## [6.8.0](https://github.com/log4js-node/log4js-node/milestone/92)
- [feat: added `log4js.isConfigured()` API](https://github.com/log4js-node/log4js-node/pull/1364) - thanks [@lamweili](https://github.com/lamweili)
- [docs: added `log4js.isConfigured()`](https://github.com/log4js-node/log4js-node/pull/1369) - thanks [@lamweili](https://github.com/lamweili)
- [feat(layout): support a specifier on %m](https://github.com/log4js-node/log4js-node/pull/1346) - thanks [@lamweili](https://github.com/lamweili)
- [fix: tilde expansion for windows](https://github.com/log4js-node/log4js-node/pull/1363) - thanks [@lamweili](https://github.com/lamweili)
- [docs: updated typescript usage](https://github.com/log4js-node/log4js-node/pull/1361) - thanks [@lamweili](https://github.com/lamweili)
- [test: improved test for fileAppender](https://github.com/log4js-node/log4js-node/pull/1365) - thanks [@lamweili](https://github.com/lamweili)
- [ci: generate coverage report in both text and html](https://github.com/log4js-node/log4js-node/pull/1368) - thanks [@lamweili](https://github.com/lamweili)
- [ci: replaced deprecated github set-output](https://github.com/log4js-node/log4js-node/pull/1351) - thanks [@lamweili](https://github.com/lamweili)
- [chore(deps): updated dependencies](https://github.com/log4js-node/log4js-node/pull/1367) - thanks [@lamweili](https://github.com/lamweili)
- chore(deps): bump streamroller from 3.1.3 to 3.1.5
- chore(deps): updated package-lock.json
- [chore(deps-dev): updated dependencies](https://github.com/log4js-node/log4js-node/pull/1366) - thanks [@lamweili](https://github.com/lamweili)
- chore(deps-dev): bump @commitlint/cli from 17.3.0 to 17.4.4
- chore(deps-dev): bump @commitlint/config-conventional from 17.3.0 to 17.4.4
- chore(deps-dev): bump eslint from 8.28.0 to 8.34.0
- chore(deps-dev): bump eslint-config-prettier from 8.5.0 to 8.6.0
- chore(deps-dev): bump eslint-import-resolver-node from 0.3.6 to 0.3.7
- chore(deps-dev): bump eslint-plugin-import from 2.26.0 to 2.27.5
- chore(deps-dev): bump fs-extra from 10.1.0 to 11.1.0
- chore(deps-dev): bump husky from 8.0.2 to 8.0.3
- chore(deps-dev): bump prettier from 2.8.0 to 2.8.4
- chore(deps-dev): bump tap from 16.3.2 to 16.3.4
- chore(deps-dev): bump typescript from 4.9.3 to 4.9.5
- chore(deps-dev): updated package-lock.json
- [chore(deps-dev): bump json5 from 1.0.1 to 1.0.2](https://github.com/log4js-node/log4js-node/pull/1357) - thanks [@Dependabot](https://github.com/dependabot)
## [6.7.1](https://github.com/log4js-node/log4js-node/milestone/91)
- [type: updated Configuration.levels type to allow for custom log levels](https://github.com/log4js-node/log4js-node/pull/1348) - thanks [@lamweili](https://github.com/lamweili)
- [docs: fixed typo in `layouts.md`](https://github.com/log4js-node/log4js-node/pull/1338) - thanks [@dtslvr](https://github.com/dtslvr)
- [chore(deps-dev): updated dependencies](https://github.com/log4js-node/log4js-node/pull/1349) - thanks [@lamweili](https://github.com/lamweili)
- chore(deps-dev): bump @commitlint/cli from 17.1.2 to 17.3.0
- chore(deps-dev): bump @commitlint/config-conventional from 17.1.0 to 17.3.0
- chore(deps-dev): bump eslint from 8.24.0 to 8.28.0
- chore(deps-dev): bump husky from 8.0.1 to 8.0.2
- chore(deps-dev): bump prettier from 2.7.1 to 2.8.0
- chore(deps-dev): bump tap from 16.3.0 to 16.3.2
- chore(deps-dev): bump typescript from 4.8.4 to 4.9.3
- chore(deps-dev): updated package-lock.json
## [6.7.0](https://github.com/log4js-node/log4js-node/milestone/90)
- [feat(log4js): if cb is passed to shutdown(), it must be a function or it will throw error immediately](https://github.com/log4js-node/log4js-node/pull/1334) - thanks [@lamweili](https://github.com/lamweili)
- [feat: patternLayout function name, class name and function alias](https://github.com/log4js-node/log4js-node/pull/1316) - thanks [@l0ner](https://github.com/l0ner)
- [refactor(#1316): code flow and readability (%C:class, %M:function, %A:alias, %F:full - in order)](https://github.com/log4js-node/log4js-node/pull/1317) - thanks [@lamweili](https://github.com/lamweili)
- [feat: add ability to use passed in Errors for callstacks and adjust how deeply you want to look for information](https://github.com/log4js-node/log4js-node/pull/1269) - thanks [@ZachHaber](https://github.com/ZachHaber)
- [fix(LoggingEvent): serde for NaN, Infinity, -Infinity, undefined](https://github.com/log4js-node/log4js-node/pull/1332) - thanks [@lamweili](https://github.com/lamweili)
- [fix: make shutdown return value consistent](https://github.com/log4js-node/log4js-node/pull/1082) - thanks [@richardhinkamp](https://github.com/richardhinkamp)
- [refactor(#1082): removed return value for `log4js.shutdown()`](https://github.com/log4js-node/log4js-node/pull/1319) - thanks [@lamweili](https://github.com/lamweili)
- [test: adjusted timeout interval for OS operations](https://github.com/log4js-node/log4js-node/pull/1318) - thanks [@lamweili](https://github.com/lamweili)
- [refactor(LoggingEvent): loop through location keys instead of hard-coding one-by-one](https://github.com/log4js-node/log4js-node/pull/1333) - thanks [@lamweili](https://github.com/lamweili)
- [docs(noLogFilter): fix heading (`Category Filter` --> `No-Log Filter`)](https://github.com/log4js-node/log4js-node/pull/1322) - thanks [@gkalpak](https://github.com/gkalpak)
- [docs(migration-guide): fix typo (`have been remove` --> `have been removed`)](https://github.com/log4js-node/log4js-node/pull/1321) - thanks [@gkalpak](https://github.com/gkalpak)
- [docs: added quotes for `just-errors` JSON property key ](https://github.com/log4js-node/log4js-node/pull/1312) - thanks [@lamweili](https://github.com/lamweili)
- [ci: skip prettier on older Node.js (8.x, 10.x, 12.x)](https://github.com/log4js-node/log4js-node/pull/1328) - thanks [@lamweili](https://github.com/lamweili)
- [ci: manually downgrade dev dependencies for older versions](https://github.com/log4js-node/log4js-node/pull/1326) - thanks [@lamweili](https://github.com/lamweili)
- [ci: removed scheduled job from codeql and separated npm audit](https://github.com/log4js-node/log4js-node/pull/1325) - thanks [@lamweili](https://github.com/lamweili)
- [chore(deps): bump typescript from 4.8.3 to 4.8.4](https://github.com/log4js-node/log4js-node/pull/1330) - thanks [@lamweili](https://github.com/lamweili)
- [chore(deps-dev): updated dependencies](https://github.com/log4js-node/log4js-node/pull/1329) - thanks [@lamweili](https://github.com/lamweili)
- chore(deps-dev): bump nyc from 14.1.1 to 15.1.0
- chore(deps-dev): bump tap from 14.11.0 to 16.3.0
- chore(deps-dev): bump eslint-plugin-prettier from 3.4.1 to 4.2.1
- chore(deps-dev): bump prettier from 1.19.1 to 2.7.1
- chore(deps-dev): updated package-lock.json
- [chore(deps): updated dependencies](https://github.com/log4js-node/log4js-node/pull/1327) - thanks [@lamweili](https://github.com/lamweili)
- chore(deps-dev): bump @commitlint/cli from 17.0.3 to 17.1.2
- chore(deps-dev): bump @commitlint/config-conventional from 17.0.3 to 17.1.0
- chore(deps-dev): bump eslint from 6.8.0 to 8.24.0
- chore(deps-dev): bump eslint-config-airbnb-base from 14.2.1 to 15.0.0
- chore(deps-dev): bump eslint-config-prettier from 6.15.0 to 8.5.0
- chore(deps-dev): bump fs-extra from 8.1.0 to 10.1.0
- chore(deps-dev): bump typescript from 4.7.4 to 4.8.3
- chore(deps): bump date-format from 4.0.13 to 4.0.14
- chore(deps): bump flatted from 3.2.6 to 3.2.7
- chore(deps): bump streamroller from 3.1.2 to 3.1.3
- chore(deps): updated package-lock.json
## [6.6.1](https://github.com/log4js-node/log4js-node/milestone/89)
- [fix: connectlogger nolog function](https://github.com/log4js-node/log4js-node/pull/1285) - thanks [@eyoboue](https://github.com/eyoboue)
- [type: corrected AppenderModule interface and Recording interface](https://github.com/log4js-node/log4js-node/pull/1304) - thanks [@lamweili](https://github.com/lamweili)
- test: extended timeout interval for OS operations - thanks [@lamweili](https://github.com/lamweili)
- test: [#1306](https://github.com/log4js-node/log4js-node/pull/1306)
- test: [#1297](https://github.com/log4js-node/log4js-node/pull/1297)
- [test: support older Node.js versions](https://github.com/log4js-node/log4js-node/pull/1295) - thanks [@lamweili](https://github.com/lamweili)
- [ci: added tests for Node.js 8.x](https://github.com/log4js-node/log4js-node/pull/1303) - thanks [@lamweili](https://github.com/lamweili)
- [ci: added tests for Node.js 10.x, 18.x](https://github.com/log4js-node/log4js-node/pull/1301) - thanks [@lamweili](https://github.com/lamweili)
- [ci: updated codeql from v1 to v2](https://github.com/log4js-node/log4js-node/pull/1302) - thanks [@lamweili](https://github.com/lamweili)
- [chore(deps-dev): bump lodash from 4.17.19 to 4.17.21](https://github.com/log4js-node/log4js-node/pull/1309) - thanks [@Dependabot](https://github.com/dependabot)
- [chore(deps-dev): bump path-parse from 1.0.6 to 1.0.7](https://github.com/log4js-node/log4js-node/pull/1308) - thanks [@Dependabot](https://github.com/dependabot)
- [chore(deps-dev): downgraded nyc from 15.1.0 to 14.1.1](https://github.com/log4js-node/log4js-node/pull/1305) - thanks [@lamweili](https://github.com/lamweili)
- [chore(deps): updated dependencies](https://github.com/log4js-node/log4js-node/pull/1296) - thanks [@lamweili](https://github.com/lamweili)
- chore(deps): bump date-format from 4.0.11 to 4.0.13
- chore(deps): bump flatted from 3.2.5 to 3.2.6
- chore(deps): bump streamroller from 3.1.1 to 3.1.2
- chore(deps-dev): bump @commitlint/cli from 17.0.2 to 17.0.3
- chore(deps-dev): bump @commitlint/config-conventional from 17.0.2 to 17.0.3
- [chore(deps-dev): bump eslint from 8.16.0 to 8.20.0](https://github.com/log4js-node/log4js-node/pull/1300)
- chore(deps-dev): bump eslint-plugin-prettier from 4.0.0 to 4.2.1
- chore(deps-dev): bump prettier from 2.6.0 to 2.7.1
- chore(deps-dev): bump tap from 16.2.0 to 16.3.0
- chore(deps-dev): bump typescript from 4.7.2 to 4.7.4
- chore(deps): updated package-lock.json
## [6.6.0](https://github.com/log4js-node/log4js-node/milestone/87)
- [feat: adding function(req, res) support to connectLogger nolog](https://github.com/log4js-node/log4js-node/pull/1279) - thanks [@eyoboue](https://github.com/eyoboue)
- [fix: ability to load CJS appenders (through .cjs extension) for ESM packages](https://github.com/log4js-node/log4js-node/pull/1280) - thanks [@lamweili](https://github.com/lamweili)
- [type: consistent typing for Logger](https://github.com/log4js-node/log4js-node/pull/1276) - thanks [@taozi0818](https://github.com/taozi0818)
- [type: Make Appender Type extensible from other modules and the user](https://github.com/log4js-node/log4js-node/pull/1267) - thanks [@ZachHaber](https://github.com/ZachHaber)
- [refactor: clearer logic for invalid level and LOG synonym](https://github.com/log4js-node/log4js-node/pull/1264) - thanks [@lamweili](https://github.com/lamweili)
- [style: ran prettier and requires prettier for ci](https://github.com/log4js-node/log4js-node/pull/1271) - thanks [@ZachHaber](https://github.com/ZachHaber)
- [docs: renamed peteriman to lamweili in changelog](https://github.com/log4js-node/log4js-node/pull/1272) - thanks [@lamweili](https://github.com/lamweili)
- [ci: replaced validate-commit-msg, fixed husky config, removed codecov](https://github.com/log4js-node/log4js-node/pull/1274) - thanks [@ZachHaber](https://github.com/ZachHaber)
- [chore(deps): updated dependencies](https://github.com/log4js-node/log4js-node/pull/1266) - thanks [@lamweili](https://github.com/lamweili)
- chore(deps-dev): bump typescript from 4.6.4 to 4.7.2
- chore(deps): bump date-format from 4.0.10 to 4.0.11
- chore(deps): updated package-lock.json
## [6.5.2](https://github.com/log4js-node/log4js-node/milestone/86)
- [type: add LogEvent.serialise](https://github.com/log4js-node/log4js-node/pull/1260) - thanks [@marrowleaves](https://github.com/marrowleaves)
## [6.5.1](https://github.com/log4js-node/log4js-node/milestone/85)
- [fix: fs.appendFileSync should use flag instead of flags](https://github.com/log4js-node/log4js-node/pull/1257) - thanks [@lamweili](https://github.com/lamweili)
- [chore(deps): updated dependencies](https://github.com/log4js-node/log4js-node/pull/1258) - thanks [@lamweili](https://github.com/lamweili)
- chore(deps): bump streamroller from 3.1.0 to 3.1.1
- chore(deps): updated package-lock.json
## [6.5.0](https://github.com/log4js-node/log4js-node/milestone/84)
- [feat: logger.log() to be synonym of logger.info()](https://github.com/log4js-node/log4js-node/pull/1254) - thanks [@lamweili](https://github.com/lamweili)
- [feat: tilde expansion for filename](https://github.com/log4js-node/log4js-node/pull/1252) - thanks [@lamweili](https://github.com/lamweili)
- [fix: better file validation](https://github.com/log4js-node/log4js-node/pull/1251) - thanks [@lamweili](https://github.com/lamweili)
- [fix: fallback for logger.log outputs nothing](https://github.com/log4js-node/log4js-node/pull/1247) - thanks [@lamweili](https://github.com/lamweili)
- [docs: updated fileAppender maxLogSize documentation](https://github.com/log4js-node/log4js-node/pull/1248) - thanks [@lamweili](https://github.com/lamweili)
- [ci: enforced 100% test coverage tests](https://github.com/log4js-node/log4js-node/pull/1253) - thanks [@lamweili](https://github.com/lamweili)
- [chore(deps): updated dependencies](https://github.com/log4js-node/log4js-node/pull/1256) - thanks [@lamweili](https://github.com/lamweili)
- chore(deps-dev): bump eslint from 8.15.0 to 8.16.0
- chore(deps): bump streamroller from 3.0.9 to 3.1.0
- chore(deps): updated package-lock.json
## [6.4.7](https://github.com/log4js-node/log4js-node/milestone/83)
- [fix: dateFileAppender unable to use units in maxLogSize](https://github.com/log4js-node/log4js-node/pull/1243) - thanks [@lamweili](https://github.com/lamweili)
- [type: added fileNameSep for FileAppender and DateFileAppender](https://github.com/log4js-node/log4js-node/pull/1241) - thanks [@lamweili](https://github.com/lamweili)
- [docs: updated usage of units for maxLogSize](https://github.com/log4js-node/log4js-node/pull/1242) - thanks [@lamweili](https://github.com/lamweili)
- [docs: updated comments in typescript def](https://github.com/log4js-node/log4js-node/pull/1240) - thanks [@lamweili](https://github.com/lamweili)
- [chore(deps): updated dependencies](https://github.com/log4js-node/log4js-node/pull/1244) - thanks [@lamweili](https://github.com/lamweili)
- chore(deps-dev): bump eslint from 8.14.0 to 8.15.0
- chore(deps-dev): bump husky from 7.0.4 to 8.0.1
- chore(deps-dev): bump tap from 16.1.0 to 16.2.0
- chore(deps-dev): bump typescript from 4.6.3 to 4.6.4
- chore(deps): bump date-format from 4.0.9 to 4.0.10
- chore(deps): bump streamroller from 3.0.8 to 3.0.9
- chore(deps): updated package-lock.json
- [chore(deps): updated dependencies](https://github.com/log4js-node/log4js-node/pull/1238) - thanks [@lamweili](https://github.com/lamweili)
- chore(deps-dev): bump tap from 16.0.1 to 16.1.0
- chore(deps-dev): updated package-lock.json
## [6.4.6](https://github.com/log4js-node/log4js-node/milestone/82)
- [chore(deps): updated dependencies](https://github.com/log4js-node/log4js-node/pull/1236) - thanks [@lamweili](https://github.com/lamweili)
- chore(deps-dev): bump eslint from 8.13.0 to 8.14.0
- chore(deps): bump date-format from 4.0.7 to 4.0.9
- chore(deps): bump streamroller from 3.0.7 to 3.0.8
- fix: [#1216](https://github.com/log4js-node/log4js-node/issues/1216) where promise rejection is not handled ([streamroller@3.0.8 changelog](https://github.com/log4js-node/streamroller/blob/master/CHANGELOG.md))
- chore(deps): updated package-lock.json
- [chore(deps): updated dependencies](https://github.com/log4js-node/log4js-node/pull/1234) - thanks [@lamweili](https://github.com/lamweili)
- chore(deps): bump fs-extra from 10.0.1 to 10.1.0
- chore(deps): updated package-lock.json
## [6.4.5](https://github.com/log4js-node/log4js-node/milestone/81)
- [fix: deserialise for enableCallStack features: filename, lineNumber, columnNumber, callStack](https://github.com/log4js-node/log4js-node/pull/1230) - thanks [@lamweili](https://github.com/lamweili)
- [fix: fileDepth for ESM](https://github.com/log4js-node/log4js-node/pull/1224) - thanks [@lamweili](https://github.com/lamweili)
- [refactor: replace deprecated String.prototype.substr()](https://github.com/log4js-node/log4js-node/pull/1223) - thanks [@CommanderRoot](https://github.com/CommanderRoot)
- [type: LogEvent types](https://github.com/log4js-node/log4js-node/pull/1231) - thanks [@lamweili](https://github.com/lamweili)
- [docs: updated typescript usage](https://github.com/log4js-node/log4js-node/pull/1229) - thanks [@lamweili](https://github.com/lamweili)
- [chore(deps): updated dependencies](https://github.com/log4js-node/log4js-node/pull/1232) - thanks [@lamweili](https://github.com/lamweili)
- chore(deps): bump date-format from 4.0.6 to 4.0.7
- chore(deps): bump streamroller from 3.0.6 to 3.0.7
- fix: [#1225](https://github.com/log4js-node/log4js-node/issues/1225) where fs-extra throws error when fs.realpath.native is undefined ([streamroller@3.0.7 changelog](https://github.com/log4js-node/streamroller/blob/master/CHANGELOG.md))
- chore(deps): updated package-lock.json
- [chore(deps): updated dependencies](https://github.com/log4js-node/log4js-node/pull/1228) - thanks [@lamweili](https://github.com/lamweili)
- chore(deps-dev): bump eslint from 8.11.0 to 8.13.0
- chore(deps-dev): bump eslint-plugin-import from 2.25.4 to 2.26.0
- chore(deps-dev): bump tap from 16.0.0 to 16.0.1
- chore(deps-dev): bump typescript from 4.6.2 to 4.6.3
- chore(deps-dev): updated package-lock.json
- [chore(deps-dev): bump minimist from 1.2.5 to 1.2.6](https://github.com/log4js-node/log4js-node/pull/1227) - thanks [@Dependabot](https://github.com/dependabot)
## [6.4.4](https://github.com/log4js-node/log4js-node/milestone/80)
- [fix: set logger.level on runtime will no longer wrongly reset useCallStack](https://github.com/log4js-node/log4js-node/pull/1217) - thanks [@lamweili](https://github.com/lamweili)
- [docs: updated docs for broken links and inaccessible pages](https://github.com/log4js-node/log4js-node/pull/1219) - thanks [@lamweili](https://github.com/lamweili)
- [docs: broken link to gelf appender](https://github.com/log4js-node/log4js-node/pull/1218) - thanks [@mattalexx](https://github.com/mattalexx)
- [docs: updated docs for appenders module loading](https://github.com/log4js-node/log4js-node/pull/985) - thanks [@leonimurilo](https://github.com/leonimurilo)
- [chore(deps): updated dependencies](https://github.com/log4js-node/log4js-node/pull/1221) - thanks [@lamweili](https://github.com/lamweili)
- chore(deps): bump streamroller from 3.0.5 to 3.0.6
- chore(deps): bump debug from 4.3.3 to 4.3.4
- chore(deps): bump date-format from 4.0.5 to 4.0.6
- chore(deps-dev): bump prettier from 2.5.1 to 2.6.0
- chore(deps): updated package-lock.json
## [6.4.3](https://github.com/log4js-node/log4js-node/milestone/79)
- [fix: added filename validation](https://github.com/log4js-node/log4js-node/pull/1201) - thanks [@lamweili](https://github.com/lamweili)
- [refactor: do not initialise default appenders as it will be done again by configure()](https://github.com/log4js-node/log4js-node/pull/1210) - thanks [@lamweili](https://github.com/lamweili)
- [refactor: defensive coding for cluster=null if require('cluster') fails in try-catch ](https://github.com/log4js-node/log4js-node/pull/1199) - thanks [@lamweili](https://github.com/lamweili)
- [refactor: removed redundant logic in tcp-serverAppender](https://github.com/log4js-node/log4js-node/pull/1198) - thanks [@lamweili](https://github.com/lamweili)
- [refactor: removed redundant logic in multiprocessAppender](https://github.com/log4js-node/log4js-node/pull/1197) - thanks [@lamweili](https://github.com/lamweili)
- test: 100% test coverage - thanks [@lamweili](https://github.com/lamweili)
- test: part 1 of 3: [#1200](https://github.com/log4js-node/log4js-node/pull/1200)
- test: part 2 of 3: [#1204](https://github.com/log4js-node/log4js-node/pull/1204)
- test: part 3 of 3: [#1205](https://github.com/log4js-node/log4js-node/pull/1205)
- [test: improved test cases](https://github.com/log4js-node/log4js-node/pull/1211)
- [docs: updated README.md with badges](https://github.com/log4js-node/log4js-node/pull/1209) - thanks [@lamweili](https://github.com/lamweili)
- [docs: added docs for istanbul ignore](https://github.com/log4js-node/log4js-node/pull/1208) - thanks [@lamweili](https://github.com/lamweili)
- [docs: updated logger api docs](https://github.com/log4js-node/log4js-node/pull/1203) - thanks [@lamweili](https://github.com/lamweili)
- [docs: updated file and fileSync appender docs](https://github.com/log4js-node/log4js-node/pull/1202) - thanks [@lamweili](https://github.com/lamweili)
- [chore(lint): improve eslint rules](https://github.com/log4js-node/log4js-node/pull/1206) - thanks [@lamweili](https://github.com/lamweili)
- [chore(deps): updated dependencies](https://github.com/log4js-node/log4js-node/pull/1207) - thanks [@lamweili](https://github.com/lamweili)
- chore(deps-dev): bump eslint from 8.10.0 to 8.11.0
- chore(deps-dev): bump eslint-config-airbnb-base from 13.2.0 to 15.0.0
- chore(deps-dev): bump eslint-config-prettier from 8.4.0 to 8.5.0
- chore(deps-dev): bump tap from 15.1.6 to 16.0.0
- chore(deps): bump date-format from 4.0.4 to 4.0.5
- chore(deps): bump streamroller from 3.0.4 to 3.0.5
- chore(deps): updated package-lock.json
## [6.4.2](https://github.com/log4js-node/log4js-node/milestone/78)
- [fix: fileSync appender to create directory recursively](https://github.com/log4js-node/log4js-node/pull/1191) - thanks [@lamweili](https://github.com/lamweili)
- [fix: serialise() for NaN, Infinity, -Infinity and undefined](https://github.com/log4js-node/log4js-node/pull/1188) - thanks [@lamweili](https://github.com/lamweili)
- [fix: connectLogger not logging on close](https://github.com/log4js-node/log4js-node/pull/1179) - thanks [@lamweili](https://github.com/lamweili)
- [refactor: defensive coding](https://github.com/log4js-node/log4js-node/pull/1183) - thanks [@lamweili](https://github.com/lamweili)
- [type: fixed Logger constructor](https://github.com/log4js-node/log4js-node/pull/1177) - thanks [@lamweili](https://github.com/lamweili)
- [test: improve test coverage](https://github.com/log4js-node/log4js-node/pull/1184) - thanks [@lamweili](https://github.com/lamweili)
- [test: refactor and replaced tap deprecation in preparation for tap v15](https://github.com/log4js-node/log4js-node/pull/1172) - thanks [@lamweili](https://github.com/lamweili)
- [test: added e2e test for multiprocess Appender](https://github.com/log4js-node/log4js-node/pull/1170) - thanks [@nicojs](https://github.com/nicojs)
- [docs: updated file appender docs](https://github.com/log4js-node/log4js-node/pull/1182) - thanks [@lamweili](https://github.com/lamweili)
- [docs: updated dateFile appender docs](https://github.com/log4js-node/log4js-node/pull/1181) - thanks [@lamweili](https://github.com/lamweili)
- [docs: corrected typo in sample code for multiFile appender](https://github.com/log4js-node/log4js-node/pull/1180) - thanks [@lamweili](https://github.com/lamweili)
- [chore(deps): updated deps-dev](https://github.com/log4js-node/log4js-node/pull/1194) - thanks [@lamweili](https://github.com/lamweili)
- chore(deps): bump date-format from 4.0.3 to 4.0.4
- chore(deps): bump streamroller from 3.0.2 to 3.0.4
- fix: [#1189](https://github.com/log4js-node/log4js-node/issues/1189) for an compatibility issue with directory creation for NodeJS < 10.12.0 ([streamroller@3.0.3 changelog](https://github.com/log4js-node/streamroller/blob/master/CHANGELOG.md))
- chore(deps-dev): bump eslint from 8.8.0 to 8.10.0
- chore(deps-dev): bump eslint-config-prettier from 8.3.0 to 8.4.0
- chore(deps-dev): bump fs-extra from 10.0.0 to 10.0.1
- chore(deps-dev): bump typescript from 4.5.5 to 4.6.2
- [chore(deps): updated deps-dev](https://github.com/log4js-node/log4js-node/pull/1185) - thanks [@lamweili](https://github.com/lamweili)
- chore(deps): bump flatted from 3.2.4 to 3.2.5
- chore(deps-dev): bump eslint from 8.7.0 to 8.8.0
- [chore(deps): updated package-lock.json](https://github.com/log4js-node/log4js-node/pull/1174) - thanks [@lamweili](https://github.com/lamweili)
- [chore(deps-dev): bump tap from 14.10.7 to 15.1.6](https://github.com/log4js-node/log4js-node/pull/1173) - thanks [@lamweili](https://github.com/lamweili)
## [6.4.1](https://github.com/log4js-node/log4js-node/milestone/77)
- [fix: startup multiprocess even when no direct appenders](https://github.com/log4js-node/log4js-node/pull/1162) - thanks [@nicojs](https://github.com/nicojs)
- [refactor: fixed eslint warnings](https://github.com/log4js-node/log4js-node/pull/1165) - thanks [@lamweili](https://github.com/lamweili)
- [refactor: additional alias for date patterns](https://github.com/log4js-node/log4js-node/pull/1163) - thanks [@lamweili](https://github.com/lamweili)
- [refactor: added emitWarning for deprecation](https://github.com/log4js-node/log4js-node/pull/1164) - thanks [@lamweili](https://github.com/lamweili)
- [type: Fixed wrong types from 6.4.0 regression](https://github.com/log4js-node/log4js-node/pull/1158) - thanks [@glasser](https://github.com/glasser)
- [docs: changed author to contributors in package.json](https://github.com/log4js-node/log4js-node/pull/1153) - thanks [@lamweili](https://github.com/lamweili)
- [chore(deps): bump node-fetch from 2.6.6 to 2.6.7](https://github.com/log4js-node/log4js-node/pull/1167) - thanks [@Dependabot](https://github.com/dependabot)
- [chore(deps-dev): bump typescript from 4.5.4 to 4.5.5](https://github.com/log4js-node/log4js-node/pull/1166) - thanks [@lamweili](https://github.com/lamweili)
## [6.4.0](https://github.com/log4js-node/log4js-node/milestone/76) - BREAKING CHANGE 💥
New default file permissions may cause external applications unable to read logs.
A [manual code/configuration change](https://github.com/log4js-node/log4js-node/pull/1141#issuecomment-1076224470) is required.
- [feat: added warnings when log() is used with invalid levels before fallbacking to INFO](https://github.com/log4js-node/log4js-node/pull/1062) - thanks [@abernh](https://github.com/abernh)
- [feat: exposed Recording](https://github.com/log4js-node/log4js-node/pull/1103) - thanks [@polo-language](https://github.com/polo-language)
- [fix: default file permission to be 0o600 instead of 0o644](https://github.com/log4js-node/log4js-node/pull/1141) - thanks [ranjit-git](https://www.huntr.dev/users/ranjit-git) and [@lamweili](https://github.com/lamweili)
- [docs: updated fileSync.md and misc comments](https://github.com/log4js-node/log4js-node/pull/1148) - thanks [@lamweili](https://github.com/lamweili)
- [fix: file descriptor leak if repeated configure()](https://github.com/log4js-node/log4js-node/pull/1113) - thanks [@lamweili](https://github.com/lamweili)
- [fix: MaxListenersExceededWarning from NodeJS](https://github.com/log4js-node/log4js-node/pull/1110) - thanks [@lamweili](https://github.com/lamweili)
- [test: added assertion for increase of SIGHUP listeners on log4js.configure()](https://github.com/log4js-node/log4js-node/pull/1142) - thanks [@lamweili](https://github.com/lamweili)
- [fix: missing TCP appender with Webpack and Typescript](https://github.com/log4js-node/log4js-node/pull/1028) - thanks [@techmunk](https://github.com/techmunk)
- [fix: dateFile appender exiting NodeJS on error](https://github.com/log4js-node/log4js-node/pull/1097) - thanks [@4eb0da](https://github.com/4eb0da)
- [refactor: using writer.writable instead of alive for checking](https://github.com/log4js-node/log4js-node/pull/1144) - thanks [@lamweili](https://github.com/lamweili)
- [fix: TCP appender exiting NodeJS on error](https://github.com/log4js-node/log4js-node/pull/1089) - thanks [@jhonatanTeixeira](https://github.com/jhonatanTeixeira)
- [fix: multiprocess appender exiting NodeJS on error](https://github.com/log4js-node/log4js-node/pull/529) - thanks [@harlentan](https://github.com/harlentan)
- [test: update fakeFS.read as graceful-fs uses it](https://github.com/log4js-node/log4js-node/pull/1127) - thanks [@lamweili](https://github.com/lamweili)
- [test: update fakeFS.realpath as fs-extra uses it](https://github.com/log4js-node/log4js-node/pull/1128) - thanks [@lamweili](https://github.com/lamweili)
- test: added tap.tearDown() to clean up test files
- test: [#1143](https://github.com/log4js-node/log4js-node/pull/1143) - thanks [@lamweili](https://github.com/lamweili)
- test: [#1022](https://github.com/log4js-node/log4js-node/pull/1022) - thanks [@abetomo](https://github.com/abetomo)
- [type: improved @types for AppenderModule](https://github.com/log4js-node/log4js-node/pull/1079) - thanks [@nicobao](https://github.com/nicobao)
- [type: Updated fileSync appender types](https://github.com/log4js-node/log4js-node/pull/1116) - thanks [@lamweili](https://github.com/lamweili)
- [type: Removed erroneous type in file appender](https://github.com/log4js-node/log4js-node/pull/1031) - thanks [@vdmtrv](https://github.com/vdmtrv)
- [type: Updated Logger.log type](https://github.com/log4js-node/log4js-node/pull/1115) - thanks [@ZLundqvist](https://github.com/ZLundqvist)
- [type: Updated Logger.\_log type](https://github.com/log4js-node/log4js-node/pull/1117) - thanks [@lamweili](https://github.com/lamweili)
- [type: Updated Logger.level type](https://github.com/log4js-node/log4js-node/pull/1118) - thanks [@lamweili](https://github.com/lamweili)
- [type: Updated Levels.getLevel type](https://github.com/log4js-node/log4js-node/pull/1072) - thanks [@saulzhong](https://github.com/saulzhong)
- [chore(deps): bump streamroller from 3.0.1 to 3.0.2](https://github.com/log4js-node/log4js-node/pull/1147) - thanks [@lamweili](https://github.com/lamweili)
- [chore(deps): bump date-format from 4.0.2 to 4.0.3](https://github.com/log4js-node/log4js-node/pull/1146) - thanks [@lamweili](https://github.com/lamweili)
- [chore(deps-dev): bump eslint from from 8.6.0 to 8.7.0](https://github.com/log4js-node/log4js-node/pull/1145) - thanks [@lamweili](https://github.com/lamweili)
- [chore(deps-dev): bump nyc from 14.1.1 to 15.1.0](https://github.com/log4js-node/log4js-node/pull/1140) - thanks [@lamweili](https://github.com/lamweili)
- [chore(deps-dev): bump eslint from 5.16.0 to 8.6.0](https://github.com/log4js-node/log4js-node/pull/1138) - thanks [@lamweili](https://github.com/lamweili)
- [chore(deps): bump flatted from 2.0.2 to 3.2.4](https://github.com/log4js-node/log4js-node/pull/1137) - thanks [@lamweili](https://github.com/lamweili)
- [chore(deps-dev): bump fs-extra from 8.1.0 to 10.0.0](https://github.com/log4js-node/log4js-node/pull/1136) - thanks [@lamweili](https://github.com/lamweili)
- [chore(deps): bump streamroller from 2.2.4 to 3.0.1](https://github.com/log4js-node/log4js-node/pull/1135) - thanks [@lamweili](https://github.com/lamweili)
- [fix: compressed file ignores dateFile appender "mode"](https://github.com/log4js-node/streamroller/pull/65) - thanks [@rnd-debug](https://github.com/rnd-debug)
- fix: [#1039](https://github.com/log4js-node/log4js-node/issues/1039) where there is an additional separator in filename ([streamroller@3.0.0 changelog](https://github.com/log4js-node/streamroller/blob/master/CHANGELOG.md))
- fix: [#1035](https://github.com/log4js-node/log4js-node/issues/1035), [#1080](https://github.com/log4js-node/log4js-node/issues/1080) for daysToKeep naming confusion ([streamroller@3.0.0 changelog](https://github.com/log4js-node/streamroller/blob/master/CHANGELOG.md))
- [refactor: migrated from daysToKeep to numBackups due to streamroller@^3.0.0](https://github.com/log4js-node/log4js-node/pull/1149) - thanks [@lamweili](https://github.com/lamweili)
- [feat: allows for zero backups](https://github.com/log4js-node/log4js-node/pull/1151) - thanks [@lamweili](https://github.com/lamweili)
- [chore(deps): bump date-format from 3.0.0 to 4.0.2](https://github.com/log4js-node/log4js-node/pull/1134) - thanks [@lamweili](https://github.com/lamweili)
- [chore(deps): updated dependencies](https://github.com/log4js-node/log4js-node/pull/1130) - thanks [@lamweili](https://github.com/lamweili)
- chore(deps-dev): bump eslint-config-prettier from 6.15.0 to 8.3.0
- chore(deps-dev): bump eslint-plugin-prettier from 3.4.1 to 4.0.0
- chore(deps-dev): bump husky from 3.1.0 to 7.0.4
- chore(deps-dev): bump prettier from 1.19.0 to 2.5.1
- chore(deps-dev): bump typescript from 3.9.10 to 4.5.4
- [chore(deps-dev): bump eslint-config-prettier from 6.15.0 to 8.3.0](https://github.com/log4js-node/log4js-node/pull/1129) - thanks [@lamweili](https://github.com/lamweili)
- [chore(deps): updated dependencies](https://github.com/log4js-node/log4js-node/pull/1121) - thanks [@lamweili](https://github.com/lamweili)
- chore(deps-dev): bump codecov from 3.6.1 to 3.8.3
- chore(deps-dev): bump eslint-config-prettier from 6.5.0 to 6.15.0
- chore(deps-dev): bump eslint-import-resolver-node from 0.3.2 to 0.3.6
- chore(deps-dev): bump eslint-plugin-import" from 2.18.2 to 2.25.4
- chore(deps-dev): bump eslint-plugin-prettier from 3.1.1 to 3.4.1
- chore(deps-dev): bump husky from 3.0.9 to 3.1.0
- chore(deps-dev): bump prettier from 1.18.2 to 1.19.1
- chore(deps-dev): bump typescript from 3.7.2 to 3.9.10
- [chore(deps): bump path-parse from 1.0.6 to 1.0.7](https://github.com/log4js-node/log4js-node/pull/1120) - thanks [@Dependabot](https://github.com/dependabot)
- [chore(deps): bump glob-parent from 5.1.1 to 5.1.2](https://github.com/log4js-node/log4js-node/pull/1084) - thanks [@Dependabot](https://github.com/dependabot)
- [chore(deps): bump hosted-git-info from 2.7.1 to 2.8.9](https://github.com/log4js-node/log4js-node/pull/1076) - thanks [@Dependabot](https://github.com/dependabot)
- [chore(deps): bump lodash from 4.17.14 to 4.17.21](https://github.com/log4js-node/log4js-node/pull/1075) - thanks [@Dependabot](https://github.com/dependabot)
- [chore(deps): bump y18n from 4.0.0 to 4.0.1](https://github.com/log4js-node/log4js-node/pull/1070) - thanks [@Dependabot](https://github.com/dependabot)
- [chore(deps): bump node-fetch from 2.6.0 to 2.6.1](https://github.com/log4js-node/log4js-node/pull/1047) - thanks [@Dependabot](https://github.com/dependabot)
- [chore(deps): bump yargs-parser from 13.1.1 to 13.1.2](https://github.com/log4js-node/log4js-node/pull/1045) - thanks [@Dependabot](https://github.com/dependabot)
- [chore(deps-dev): bump codecov from 3.6.5 to 3.7.1](https://github.com/log4js-node/log4js-node/pull/1033) - thanks [@Dependabot](https://github.com/dependabot)
## [6.3.0](https://github.com/log4js-node/log4js-node/milestone/75)
- [Add option to file appender to remove ANSI colours](https://github.com/log4js-node/log4js-node/pull/1001) - thanks [@BlueCocoa](https://github.com/BlueCocoa)
- [Do not create appender if no categories use it](https://github.com/log4js-node/log4js-node/pull/1002) - thanks [@rnd-debug](https://github.com/rnd-debug)
- [Docs: better categories inheritance description](https://github.com/log4js-node/log4js-node/pull/1003) - thanks [@rnd-debug](https://github.com/rnd-debug)
- [Better jsdoc docs](https://github.com/log4js-node/log4js-node/pull/1004) - thanks [@wataash](https://github.com/wataash)
- [Typescript: access category field in Logger](https://github.com/log4js-node/log4js-node/pull/1006) - thanks [@rtvd](https://github.com/rtvd)
- [Docs: influxdb appender](https://github.com/log4js-node/log4js-node/pull/1014) - thanks [@rnd-debug](https://github.com/rnd-debug)
- [Support for fileSync appender in webpack](https://github.com/log4js-node/log4js-node/pull/1015) - thanks [@lauren-li](https://github.com/lauren-li)
- [Docs: UDP appender](https://github.com/log4js-node/log4js-node/pull/1018) - thanks [@iassasin](https://github.com/iassasin)
- [Style: spaces and tabs](https://github.com/log4js-node/log4js-node/pull/1016) - thanks [@abetomo](https://github.com/abetomo)
## [6.2.1](https://github.com/log4js-node/log4js-node/milestone/74)
- [Update streamroller to 2.2.4 to fix incorrect filename matching during log rotation](https://github.com/log4js-node/log4js-node/pull/996)
## [6.2.0](https://github.com/log4js-node/log4js-node/milestone/73)
- [Add custom message end token to TCP appender](https://github.com/log4js-node/log4js-node/pull/994) - thanks [@rnd-debug](https://github.com/rnd-debug)
- [Update acorn (dev dep of a dep)](https://github.com/log4js-node/log4js-node/pull/992) - thanks Github Robots.
## [6.1.2](https://github.com/log4js-node/log4js-node/milestone/72)
- [Handle out-of-order appender loading](https://github.com/log4js-node/log4js-node/pull/986) - thanks [@mvastola](https://github.com/mvastola)
## [6.1.1](https://github.com/log4js-node/log4js-node/milestone/71)
- [Add guards for undefined shutdown callback](https://github.com/log4js-node/log4js-node/pull/972) - thanks [@aaron-edwards](https://github.com/aaron-edwards)
- [Ignore .bob files](https://github.com/log4js-node/log4js-node/pull/975) - thanks [@cesine](https://github.com/cesine)
- [Add mark method to type definitions](https://github.com/log4js-node/log4js-node/pull/984) - thanks [@techmunk](https://github.com/techmunk)
## [6.1.0](https://github.com/log4js-node/log4js-node/milestone/70)
- [Add pause event to dateFile appender](https://github.com/log4js-node/log4js-node/pull/965) - thanks [@shayantabatabaee](https://github.com/shayantabatabaee)
- [Add pause event to file appender](https://github.com/log4js-node/log4js-node/pull/938) - thanks [@shayantabatabaee](https://github.com/shayantabatabaee)
- [Add pause/resume event to docs](https://github.com/log4js-node/log4js-node/pull/966)
## [6.0.0](https://github.com/log4js-node/log4js-node/milestone/69)
- [Update streamroller to fix unhandled promise rejection](https://github.com/log4js-node/log4js-node/pull/962)
- [Updated date-format library](https://github.com/log4js-node/log4js-node/pull/960)
## [5.3.0](https://github.com/log4js-node/log4js-node/milestone/68)
- [Padding and truncation changes](https://github.com/log4js-node/log4js-node/pull/956)
## [5.2.2](https://github.com/log4js-node/log4js-node/milestone/67)
- [Update streamroller to fix overwriting old files when using date rolling](https://github.com/log4js-node/log4js-node/pull/951)
## [5.2.1](https://github.com/log4js-node/log4js-node/milestone/66)
- [Update streamroller to fix numToKeep not working with dateFile pattern that is all digits](https://github.com/log4js-node/log4js-node/pull/949)
## [5.2.0](https://github.com/log4js-node/log4js-node/milestone/65)
- [Update streamroller to 2.2.0 (copy and truncate when file is busy)](https://github.com/log4js-node/log4js-node/pull/948)
## [5.1.0](https://github.com/log4js-node/log4js-node/milestone/64)
- [Update streamroller to 2.1.0 (windows fixes)](https://github.com/log4js-node/log4js-node/pull/933)
## [5.0.0](https://github.com/log4js-node/log4js-node/milestone/61)
- [Update streamroller to 2.0.0 (remove support for node v6)](https://github.com/log4js-node/log4js-node/pull/922)
- [Update dependencies (mostly dev deps)](https://github.com/log4js-node/log4js-node/pull/923)
- [Fix error when cluster not available](https://github.com/log4js-node/log4js-node/pull/930)
- [Test coverage improvements](https://github.com/log4js-node/log4js-node/pull/925)
## [4.5.1](https://github.com/log4js-node/log4js-node/milestone/63)
- [Update streamroller 1.0.5 -> 1.0.6 (to fix overwriting old backup log files)](https://github.com/log4js-node/log4js-node/pull/918)
- [Dependency update: lodash 4.17.4 (dependency of a dependency, not log4js)](https://github.com/log4js-node/log4js-node/pull/917) - thanks Github Automated Security Thing.
- [Dependency update: lodash 4.4.0 -> 4.5.0 (dependency of a dependency, not log4js)](https://github.com/log4js-node/log4js-node/pull/915) - thanks Github Automated Security Thing.
## [4.5.0](https://github.com/log4js-node/log4js-node/milestone/62)
- [Override call stack parsing](https://github.com/log4js-node/log4js-node/pull/914) - thanks [@rommni](https://github.com/rommni)
- [patternLayout filename depth token](https://github.com/log4js-node/log4js-node/pull/913) - thanks [@rommni](https://github.com/rommni)
## [4.4.0](https://github.com/log4js-node/log4js-node/milestone/60)
- [Add option to pass appender module in config](https://github.com/log4js-node/log4js-node/pull/833) - thanks [@kaxelson](https://github.com/kaxelson)
- [Added docs for passing appender module](https://github.com/log4js-node/log4js-node/pull/904)
- [Updated dependencies](https://github.com/log4js-node/log4js-node/pull/900)
## [4.3.2](https://github.com/log4js-node/log4js-node/milestone/59)
- [Types for enableCallStack](https://github.com/log4js-node/log4js-node/pull/897) - thanks [@citrusjunoss](https://github.com/citrusjunoss)
## [4.3.1](https://github.com/log4js-node/log4js-node/milestone/58)
- [Fix for maxLogSize in dateFile appender](https://github.com/log4js-node/log4js-node/pull/889)
## [4.3.0](https://github.com/log4js-node/log4js-node/milestone/57)
- [Feature: line number support](https://github.com/log4js-node/log4js-node/pull/879) - thanks [@victor0801x](https://github.com/victor0801x)
- [Fix for missing core appenders in webpack](https://github.com/log4js-node/log4js-node/pull/882)
## [4.2.0](https://github.com/log4js-node/log4js-node/milestone/56)
- [Feature: add appender and level inheritance](https://github.com/log4js-node/log4js-node/pull/863) - thanks [@pharapiak](https://github.com/pharapiak)
- [Feature: add response to context for connectLogger](https://github.com/log4js-node/log4js-node/pull/862) - thanks [@leak4mk0](https://github.com/leak4mk0)
- [Fix for broken sighup handler](https://github.com/log4js-node/log4js-node/pull/873)
- [Add missing types for Level](https://github.com/log4js-node/log4js-node/pull/872) - thanks [@Ivkaa](https://github.com/Ivkaa)
- [Typescript fixes for connect logger context](https://github.com/log4js-node/log4js-node/pull/876) - thanks [@leak4mk0](https://github.com/leak4mk0)
- [Upgrade to streamroller-1.0.5 to fix log rotation bug](https://github.com/log4js-node/log4js-node/pull/878)
## [4.1.1](https://github.com/log4js-node/log4js-node/milestone/55)
- [Various test fixes for node v12](https://github.com/log4js-node/log4js-node/pull/870)
- [Fix layout problem in node v12](https://github.com/log4js-node/log4js-node/pull/860) - thanks [@bjornstar](https://github.com/bjornstar)
- [Add missing types for addLevels](https://github.com/log4js-node/log4js-node/pull/867) - thanks [@Ivkaa](https://github.com/Ivkaa)
- [Allow any return type for layout function](https://github.com/log4js-node/log4js-node/pull/845) - thanks [@xinbenlv](https://github.com/xinbenlv)
## [4.1.0](https://github.com/log4js-node/log4js-node/milestone/54)
- Updated streamroller to 1.0.4, to fix a bug where the inital size of an existing file was ignored when appending
- [Updated streamroller to 1.0.3](https://github.com/log4js-node/log4js-node/pull/841), to fix a crash bug if the date pattern was all digits.
- [Updated dependencies](https://github.com/log4js-node/log4js-node/pull/840)
## Previous versions
Change information for older versions can be found by looking at the [milestones](https://github.com/log4js-node/log4js-node/milestones) in github.

13
my-app/node_modules/log4js/LICENSE generated vendored Executable file
View file

@ -0,0 +1,13 @@
Copyright 2015 Gareth Jones (with contributions from many other people)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

120
my-app/node_modules/log4js/README.md generated vendored Executable file
View file

@ -0,0 +1,120 @@
# log4js-node [![CodeQL](https://github.com/log4js-node/log4js-node/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/log4js-node/log4js-node/actions/workflows/codeql-analysis.yml) [![Node.js CI](https://github.com/log4js-node/log4js-node/actions/workflows/node.js.yml/badge.svg)](https://github.com/log4js-node/log4js-node/actions/workflows/node.js.yml)
[![NPM](https://nodei.co/npm/log4js.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/log4js/)
This is a conversion of the [log4js](https://github.com/stritti/log4js)
framework to work with [node](http://nodejs.org). I started out just stripping out the browser-specific code and tidying up some of the javascript to work better in node. It grew from there. Although it's got a similar name to the Java library [log4j](https://logging.apache.org/log4j/2.x/), thinking that it will behave the same way will only bring you sorrow and confusion.
The full documentation is available [here](https://log4js-node.github.io/log4js-node/).
[Changes in version 3.x](https://log4js-node.github.io/log4js-node/v3-changes.md)
There have been a few changes between log4js 1.x and 2.x (and 0.x too). You should probably read this [migration guide](https://log4js-node.github.io/log4js-node/migration-guide.html) if things aren't working.
Out of the box it supports the following features:
- coloured console logging to stdout or stderr
- file appender, with configurable log rolling based on file size or date
- a logger for connect/express servers
- configurable log message layout/patterns
- different log levels for different log categories (make some parts of your app log as DEBUG, others only ERRORS, etc.)
Optional appenders are available:
- [SMTP](https://github.com/log4js-node/smtp)
- [GELF](https://github.com/log4js-node/gelf)
- [Loggly](https://github.com/log4js-node/loggly)
- Logstash ([UDP](https://github.com/log4js-node/logstashUDP) and [HTTP](https://github.com/log4js-node/logstashHTTP))
- logFaces ([UDP](https://github.com/log4js-node/logFaces-UDP) and [HTTP](https://github.com/log4js-node/logFaces-HTTP))
- [RabbitMQ](https://github.com/log4js-node/rabbitmq)
- [Redis](https://github.com/log4js-node/redis)
- [Hipchat](https://github.com/log4js-node/hipchat)
- [Slack](https://github.com/log4js-node/slack)
- [mailgun](https://github.com/log4js-node/mailgun)
- [InfluxDB](https://github.com/rnd-debug/log4js-influxdb-appender)
## Getting help
Having problems? Jump on the [slack](https://join.slack.com/t/log4js-node/shared_invite/enQtODkzMDQ3MzExMDczLWUzZmY0MmI0YWI1ZjFhODY0YjI0YmU1N2U5ZTRkOTYyYzg3MjY5NWI4M2FjZThjYjdiOGM0NjU2NzBmYTJjOGI) channel, or create an issue. If you want to help out with the development, the slack channel is a good place to go as well.
## installation
```bash
npm install log4js
```
## usage
Minimalist version:
```javascript
var log4js = require("log4js");
var logger = log4js.getLogger();
logger.level = "debug";
logger.debug("Some debug messages");
```
By default, log4js will not output any logs (so that it can safely be used in libraries). The `level` for the `default` category is set to `OFF`. To enable logs, set the level (as in the example). This will then output to stdout with the coloured layout (thanks to [masylum](http://github.com/masylum)), so for the above you would see:
```bash
[2010-01-17 11:43:37.987] [DEBUG] [default] - Some debug messages
```
See example.js for a full example, but here's a snippet (also in `examples/fromreadme.js`):
```javascript
const log4js = require("log4js");
log4js.configure({
appenders: { cheese: { type: "file", filename: "cheese.log" } },
categories: { default: { appenders: ["cheese"], level: "error" } },
});
const logger = log4js.getLogger("cheese");
logger.trace("Entering cheese testing");
logger.debug("Got cheese.");
logger.info("Cheese is Comté.");
logger.warn("Cheese is quite smelly.");
logger.error("Cheese is too ripe!");
logger.fatal("Cheese was breeding ground for listeria.");
```
Output (in `cheese.log`):
```bash
[2010-01-17 11:43:37.987] [ERROR] cheese - Cheese is too ripe!
[2010-01-17 11:43:37.990] [FATAL] cheese - Cheese was breeding ground for listeria.
```
## Note for library makers
If you're writing a library and would like to include support for log4js, without introducing a dependency headache for your users, take a look at [log4js-api](https://github.com/log4js-node/log4js-api).
## Documentation
Available [here](https://log4js-node.github.io/log4js-node/).
There's also [an example application](https://github.com/log4js-node/log4js-example).
## TypeScript
```ts
import * as log4js from "log4js";
log4js.configure({
appenders: { cheese: { type: "file", filename: "cheese.log" } },
categories: { default: { appenders: ["cheese"], level: "error" } },
});
const logger = log4js.getLogger();
logger.level = "debug";
logger.debug("Some debug messages");
```
## Contributing
We're always looking for people to help out. Jump on [slack](https://join.slack.com/t/log4js-node/shared_invite/enQtODkzMDQ3MzExMDczLWUzZmY0MmI0YWI1ZjFhODY0YjI0YmU1N2U5ZTRkOTYyYzg3MjY5NWI4M2FjZThjYjdiOGM0NjU2NzBmYTJjOGI) and discuss what you want to do. Also, take a look at the [rules](https://log4js-node.github.io/log4js-node/contrib-guidelines.html) before submitting a pull request.
## License
The original log4js was distributed under the Apache 2.0 License, and so is this. I've tried to
keep the original copyright and author credits in place, except in sections that I have rewritten
extensively.

19
my-app/node_modules/log4js/SECURITY.md generated vendored Executable file
View file

@ -0,0 +1,19 @@
# Security Policy
## Supported Versions
We're aiming to only support the latest major version of log4js. Older than that is usually _very_ old.
| Version | Supported |
| ------- | ------------------ |
| 6.x | :white_check_mark: |
| < 6.0 | :x: |
## Reporting a Vulnerability
Report vulnerabilities via email to:
- Gareth Jones <gareth.nomiddlename@gmail.com>
- Lam Wei Li <lam_wei_li@hotmail.com>
Please put "[log4js:security]" in the subject line. We will aim to respond within a day or two.

157
my-app/node_modules/log4js/lib/LoggingEvent.js generated vendored Executable file
View file

@ -0,0 +1,157 @@
/* eslint max-classes-per-file: ["error", 2] */
/* eslint no-underscore-dangle: ["error", { "allow": ["_getLocationKeys"] }] */
const flatted = require('flatted');
const levels = require('./levels');
class SerDe {
constructor() {
const deserialise = {
__LOG4JS_undefined__: undefined,
__LOG4JS_NaN__: Number('abc'),
__LOG4JS_Infinity__: 1 / 0,
'__LOG4JS_-Infinity__': -1 / 0,
};
this.deMap = deserialise;
this.serMap = {};
Object.keys(this.deMap).forEach((key) => {
const value = this.deMap[key];
this.serMap[value] = key;
});
}
canSerialise(key) {
if (typeof key === 'string') return false;
return key in this.serMap;
}
serialise(key) {
if (this.canSerialise(key)) return this.serMap[key];
return key;
}
canDeserialise(key) {
return key in this.deMap;
}
deserialise(key) {
if (this.canDeserialise(key)) return this.deMap[key];
return key;
}
}
const serde = new SerDe();
/**
* @name LoggingEvent
* @namespace Log4js
*/
class LoggingEvent {
/**
* Models a logging event.
* @constructor
* @param {string} categoryName name of category
* @param {Log4js.Level} level level of message
* @param {Array} data objects to log
* @param {Error} [error]
* @author Seth Chisamore
*/
constructor(categoryName, level, data, context, location, error) {
this.startTime = new Date();
this.categoryName = categoryName;
this.data = data;
this.level = level;
this.context = Object.assign({}, context); // eslint-disable-line prefer-object-spread
this.pid = process.pid;
this.error = error;
if (typeof location !== 'undefined') {
if (!location || typeof location !== 'object' || Array.isArray(location))
throw new TypeError(
'Invalid location type passed to LoggingEvent constructor'
);
this.constructor._getLocationKeys().forEach((key) => {
if (typeof location[key] !== 'undefined') this[key] = location[key];
});
}
}
/** @private */
static _getLocationKeys() {
return [
'fileName',
'lineNumber',
'columnNumber',
'callStack',
'className',
'functionName',
'functionAlias',
'callerName',
];
}
serialise() {
return flatted.stringify(this, (key, value) => {
// JSON.stringify(new Error('test')) returns {}, which is not really useful for us.
// The following allows us to serialize errors (semi) correctly.
if (value instanceof Error) {
// eslint-disable-next-line prefer-object-spread
value = Object.assign(
{ message: value.message, stack: value.stack },
value
);
}
// JSON.stringify({a: Number('abc'), b: 1/0, c: -1/0}) returns {a: null, b: null, c: null}.
// The following allows us to serialize to NaN, Infinity and -Infinity correctly.
// JSON.stringify([undefined]) returns [null].
// The following allows us to serialize to undefined correctly.
return serde.serialise(value);
});
}
static deserialise(serialised) {
let event;
try {
const rehydratedEvent = flatted.parse(serialised, (key, value) => {
if (value && value.message && value.stack) {
const fakeError = new Error(value);
Object.keys(value).forEach((k) => {
fakeError[k] = value[k];
});
value = fakeError;
}
return serde.deserialise(value);
});
this._getLocationKeys().forEach((key) => {
if (typeof rehydratedEvent[key] !== 'undefined') {
if (!rehydratedEvent.location) rehydratedEvent.location = {};
rehydratedEvent.location[key] = rehydratedEvent[key];
}
});
event = new LoggingEvent(
rehydratedEvent.categoryName,
levels.getLevel(rehydratedEvent.level.levelStr),
rehydratedEvent.data,
rehydratedEvent.context,
rehydratedEvent.location,
rehydratedEvent.error
);
event.startTime = new Date(rehydratedEvent.startTime);
event.pid = rehydratedEvent.pid;
if (rehydratedEvent.cluster) {
event.cluster = rehydratedEvent.cluster;
}
} catch (e) {
event = new LoggingEvent('log4js', levels.ERROR, [
'Unable to parse log:',
serialised,
'because: ',
e,
]);
}
return event;
}
}
module.exports = LoggingEvent;

46
my-app/node_modules/log4js/lib/appenders/adapters.js generated vendored Executable file
View file

@ -0,0 +1,46 @@
function maxFileSizeUnitTransform(maxLogSize) {
if (typeof maxLogSize === 'number' && Number.isInteger(maxLogSize)) {
return maxLogSize;
}
const units = {
K: 1024,
M: 1024 * 1024,
G: 1024 * 1024 * 1024,
};
const validUnit = Object.keys(units);
const unit = maxLogSize.slice(-1).toLocaleUpperCase();
const value = maxLogSize.slice(0, -1).trim();
if (validUnit.indexOf(unit) < 0 || !Number.isInteger(Number(value))) {
throw Error(`maxLogSize: "${maxLogSize}" is invalid`);
} else {
return value * units[unit];
}
}
function adapter(configAdapter, config) {
const newConfig = Object.assign({}, config); // eslint-disable-line prefer-object-spread
Object.keys(configAdapter).forEach((key) => {
if (newConfig[key]) {
newConfig[key] = configAdapter[key](config[key]);
}
});
return newConfig;
}
function fileAppenderAdapter(config) {
const configAdapter = {
maxLogSize: maxFileSizeUnitTransform,
};
return adapter(configAdapter, config);
}
const adapters = {
dateFile: fileAppenderAdapter,
file: fileAppenderAdapter,
fileSync: fileAppenderAdapter,
};
module.exports.modifyConfig = (config) =>
adapters[config.type] ? adapters[config.type](config) : config;

19
my-app/node_modules/log4js/lib/appenders/categoryFilter.js generated vendored Executable file
View file

@ -0,0 +1,19 @@
const debug = require('debug')('log4js:categoryFilter');
function categoryFilter(excludes, appender) {
if (typeof excludes === 'string') excludes = [excludes];
return (logEvent) => {
debug(`Checking ${logEvent.categoryName} against ${excludes}`);
if (excludes.indexOf(logEvent.categoryName) === -1) {
debug('Not excluded, sending to appender');
appender(logEvent);
}
};
}
function configure(config, layouts, findAppender) {
const appender = findAppender(config.appender);
return categoryFilter(config.exclude, appender);
}
module.exports.configure = configure;

18
my-app/node_modules/log4js/lib/appenders/console.js generated vendored Executable file
View file

@ -0,0 +1,18 @@
// eslint-disable-next-line no-console
const consoleLog = console.log.bind(console);
function consoleAppender(layout, timezoneOffset) {
return (loggingEvent) => {
consoleLog(layout(loggingEvent, timezoneOffset));
};
}
function configure(config, layouts) {
let layout = layouts.colouredLayout;
if (config.layout) {
layout = layouts.layout(config.layout.type, config.layout);
}
return consoleAppender(layout, config.timezoneOffset);
}
module.exports.configure = configure;

76
my-app/node_modules/log4js/lib/appenders/dateFile.js generated vendored Executable file
View file

@ -0,0 +1,76 @@
const streams = require('streamroller');
const os = require('os');
const eol = os.EOL;
function openTheStream(filename, pattern, options) {
const stream = new streams.DateRollingFileStream(filename, pattern, options);
stream.on('error', (err) => {
// eslint-disable-next-line no-console
console.error(
'log4js.dateFileAppender - Writing to file %s, error happened ',
filename,
err
);
});
stream.on('drain', () => {
process.emit('log4js:pause', false);
});
return stream;
}
/**
* File appender that rolls files according to a date pattern.
* @param filename base filename.
* @param pattern the format that will be added to the end of filename when rolling,
* also used to check when to roll files - defaults to '.yyyy-MM-dd'
* @param layout layout function for log messages - defaults to basicLayout
* @param options - options to be passed to the underlying stream
* @param timezoneOffset - optional timezone offset in minutes (default system local)
*/
function appender(filename, pattern, layout, options, timezoneOffset) {
// the options for file appender use maxLogSize, but the docs say any file appender
// options should work for dateFile as well.
options.maxSize = options.maxLogSize;
const writer = openTheStream(filename, pattern, options);
const app = function (logEvent) {
if (!writer.writable) {
return;
}
if (!writer.write(layout(logEvent, timezoneOffset) + eol, 'utf8')) {
process.emit('log4js:pause', true);
}
};
app.shutdown = function (complete) {
writer.end('', 'utf-8', complete);
};
return app;
}
function configure(config, layouts) {
let layout = layouts.basicLayout;
if (config.layout) {
layout = layouts.layout(config.layout.type, config.layout);
}
if (!config.alwaysIncludePattern) {
config.alwaysIncludePattern = false;
}
// security default (instead of relying on streamroller default)
config.mode = config.mode || 0o600;
return appender(
config.filename,
config.pattern,
layout,
config,
config.timezoneOffset
);
}
module.exports.configure = configure;

154
my-app/node_modules/log4js/lib/appenders/file.js generated vendored Executable file
View file

@ -0,0 +1,154 @@
const debug = require('debug')('log4js:file');
const path = require('path');
const streams = require('streamroller');
const os = require('os');
const eol = os.EOL;
let mainSighupListenerStarted = false;
const sighupListeners = new Set();
function mainSighupHandler() {
sighupListeners.forEach((app) => {
app.sighupHandler();
});
}
/**
* File Appender writing the logs to a text file. Supports rolling of logs by size.
*
* @param file the file log messages will be written to
* @param layout a function that takes a logEvent and returns a string
* (defaults to basicLayout).
* @param logSize - the maximum size (in bytes) for a log file,
* if not provided then logs won't be rotated.
* @param numBackups - the number of log files to keep after logSize
* has been reached (default 5)
* @param options - options to be passed to the underlying stream
* @param timezoneOffset - optional timezone offset in minutes (default system local)
*/
function fileAppender(
file,
layout,
logSize,
numBackups,
options,
timezoneOffset
) {
if (typeof file !== 'string' || file.length === 0) {
throw new Error(`Invalid filename: ${file}`);
} else if (file.endsWith(path.sep)) {
throw new Error(`Filename is a directory: ${file}`);
} else if (file.indexOf(`~${path.sep}`) === 0) {
// handle ~ expansion: https://github.com/nodejs/node/issues/684
// exclude ~ and ~filename as these can be valid files
file = file.replace('~', os.homedir());
}
file = path.normalize(file);
numBackups = !numBackups && numBackups !== 0 ? 5 : numBackups;
debug(
'Creating file appender (',
file,
', ',
logSize,
', ',
numBackups,
', ',
options,
', ',
timezoneOffset,
')'
);
function openTheStream(filePath, fileSize, numFiles, opt) {
const stream = new streams.RollingFileStream(
filePath,
fileSize,
numFiles,
opt
);
stream.on('error', (err) => {
// eslint-disable-next-line no-console
console.error(
'log4js.fileAppender - Writing to file %s, error happened ',
filePath,
err
);
});
stream.on('drain', () => {
process.emit('log4js:pause', false);
});
return stream;
}
let writer = openTheStream(file, logSize, numBackups, options);
const app = function (loggingEvent) {
if (!writer.writable) {
return;
}
if (options.removeColor === true) {
// eslint-disable-next-line no-control-regex
const regex = /\x1b[[0-9;]*m/g;
loggingEvent.data = loggingEvent.data.map((d) => {
if (typeof d === 'string') return d.replace(regex, '');
return d;
});
}
if (!writer.write(layout(loggingEvent, timezoneOffset) + eol, 'utf8')) {
process.emit('log4js:pause', true);
}
};
app.reopen = function () {
writer.end(() => {
writer = openTheStream(file, logSize, numBackups, options);
});
};
app.sighupHandler = function () {
debug('SIGHUP handler called.');
app.reopen();
};
app.shutdown = function (complete) {
sighupListeners.delete(app);
if (sighupListeners.size === 0 && mainSighupListenerStarted) {
process.removeListener('SIGHUP', mainSighupHandler);
mainSighupListenerStarted = false;
}
writer.end('', 'utf-8', complete);
};
// On SIGHUP, close and reopen all files. This allows this appender to work with
// logrotate. Note that if you are using logrotate, you should not set
// `logSize`.
sighupListeners.add(app);
if (!mainSighupListenerStarted) {
process.on('SIGHUP', mainSighupHandler);
mainSighupListenerStarted = true;
}
return app;
}
function configure(config, layouts) {
let layout = layouts.basicLayout;
if (config.layout) {
layout = layouts.layout(config.layout.type, config.layout);
}
// security default (instead of relying on streamroller default)
config.mode = config.mode || 0o600;
return fileAppender(
config.filename,
layout,
config.maxLogSize,
config.backups,
config,
config.timezoneOffset
);
}
module.exports.configure = configure;

258
my-app/node_modules/log4js/lib/appenders/fileSync.js generated vendored Executable file
View file

@ -0,0 +1,258 @@
const debug = require('debug')('log4js:fileSync');
const path = require('path');
const fs = require('fs');
const os = require('os');
const eol = os.EOL;
function touchFile(file, options) {
// attempt to create the directory
const mkdir = (dir) => {
try {
return fs.mkdirSync(dir, { recursive: true });
} catch (e) {
// backward-compatible fs.mkdirSync for nodejs pre-10.12.0 (without recursive option)
// recursive creation of parent first
if (e.code === 'ENOENT') {
mkdir(path.dirname(dir));
return mkdir(dir);
}
// throw error for all except EEXIST and EROFS (read-only filesystem)
if (e.code !== 'EEXIST' && e.code !== 'EROFS') {
throw e;
}
// EEXIST: throw if file and not directory
// EROFS : throw if directory not found
else {
try {
if (fs.statSync(dir).isDirectory()) {
return dir;
}
throw e;
} catch (err) {
throw e;
}
}
}
};
mkdir(path.dirname(file));
// try to throw EISDIR, EROFS, EACCES
fs.appendFileSync(file, '', { mode: options.mode, flag: options.flags });
}
class RollingFileSync {
constructor(filename, maxLogSize, backups, options) {
debug('In RollingFileStream');
if (maxLogSize < 0) {
throw new Error(`maxLogSize (${maxLogSize}) should be > 0`);
}
this.filename = filename;
this.size = maxLogSize;
this.backups = backups;
this.options = options;
this.currentSize = 0;
function currentFileSize(file) {
let fileSize = 0;
try {
fileSize = fs.statSync(file).size;
} catch (e) {
// file does not exist
touchFile(file, options);
}
return fileSize;
}
this.currentSize = currentFileSize(this.filename);
}
shouldRoll() {
debug(
'should roll with current size %d, and max size %d',
this.currentSize,
this.size
);
return this.currentSize >= this.size;
}
roll(filename) {
const that = this;
const nameMatcher = new RegExp(`^${path.basename(filename)}`);
function justTheseFiles(item) {
return nameMatcher.test(item);
}
function index(filename_) {
return (
parseInt(filename_.slice(`${path.basename(filename)}.`.length), 10) || 0
);
}
function byIndex(a, b) {
return index(a) - index(b);
}
function increaseFileIndex(fileToRename) {
const idx = index(fileToRename);
debug(`Index of ${fileToRename} is ${idx}`);
if (that.backups === 0) {
fs.truncateSync(filename, 0);
} else if (idx < that.backups) {
// on windows, you can get a EEXIST error if you rename a file to an existing file
// so, we'll try to delete the file we're renaming to first
try {
fs.unlinkSync(`${filename}.${idx + 1}`);
} catch (e) {
// ignore err: if we could not delete, it's most likely that it doesn't exist
}
debug(`Renaming ${fileToRename} -> ${filename}.${idx + 1}`);
fs.renameSync(
path.join(path.dirname(filename), fileToRename),
`${filename}.${idx + 1}`
);
}
}
function renameTheFiles() {
// roll the backups (rename file.n to file.n+1, where n <= numBackups)
debug('Renaming the old files');
const files = fs.readdirSync(path.dirname(filename));
files
.filter(justTheseFiles)
.sort(byIndex)
.reverse()
.forEach(increaseFileIndex);
}
debug('Rolling, rolling, rolling');
renameTheFiles();
}
// eslint-disable-next-line no-unused-vars
write(chunk, encoding) {
const that = this;
function writeTheChunk() {
debug('writing the chunk to the file');
that.currentSize += chunk.length;
fs.appendFileSync(that.filename, chunk);
}
debug('in write');
if (this.shouldRoll()) {
this.currentSize = 0;
this.roll(this.filename);
}
writeTheChunk();
}
}
/**
* File Appender writing the logs to a text file. Supports rolling of logs by size.
*
* @param file the file log messages will be written to
* @param layout a function that takes a logevent and returns a string
* (defaults to basicLayout).
* @param logSize - the maximum size (in bytes) for a log file,
* if not provided then logs won't be rotated.
* @param numBackups - the number of log files to keep after logSize
* has been reached (default 5)
* @param options - options to be passed to the underlying stream
* @param timezoneOffset - optional timezone offset in minutes (default system local)
*/
function fileAppender(
file,
layout,
logSize,
numBackups,
options,
timezoneOffset
) {
if (typeof file !== 'string' || file.length === 0) {
throw new Error(`Invalid filename: ${file}`);
} else if (file.endsWith(path.sep)) {
throw new Error(`Filename is a directory: ${file}`);
} else if (file.indexOf(`~${path.sep}`) === 0) {
// handle ~ expansion: https://github.com/nodejs/node/issues/684
// exclude ~ and ~filename as these can be valid files
file = file.replace('~', os.homedir());
}
file = path.normalize(file);
numBackups = !numBackups && numBackups !== 0 ? 5 : numBackups;
debug(
'Creating fileSync appender (',
file,
', ',
logSize,
', ',
numBackups,
', ',
options,
', ',
timezoneOffset,
')'
);
function openTheStream(filePath, fileSize, numFiles) {
let stream;
if (fileSize) {
stream = new RollingFileSync(filePath, fileSize, numFiles, options);
} else {
stream = ((f) => {
// touch the file to apply flags (like w to truncate the file)
touchFile(f, options);
return {
write(data) {
fs.appendFileSync(f, data);
},
};
})(filePath);
}
return stream;
}
const logFile = openTheStream(file, logSize, numBackups);
return (loggingEvent) => {
logFile.write(layout(loggingEvent, timezoneOffset) + eol);
};
}
function configure(config, layouts) {
let layout = layouts.basicLayout;
if (config.layout) {
layout = layouts.layout(config.layout.type, config.layout);
}
const options = {
flags: config.flags || 'a',
encoding: config.encoding || 'utf8',
mode: config.mode || 0o600,
};
return fileAppender(
config.filename,
layout,
config.maxLogSize,
config.backups,
options,
config.timezoneOffset
);
}
module.exports.configure = configure;

0
my-app/node_modules/log4js/lib/appenders/ignoreBrowser.js generated vendored Executable file
View file

182
my-app/node_modules/log4js/lib/appenders/index.js generated vendored Executable file
View file

@ -0,0 +1,182 @@
const path = require('path');
const debug = require('debug')('log4js:appenders');
const configuration = require('../configuration');
const clustering = require('../clustering');
const levels = require('../levels');
const layouts = require('../layouts');
const adapters = require('./adapters');
// pre-load the core appenders so that webpack can find them
const coreAppenders = new Map();
coreAppenders.set('console', require('./console'));
coreAppenders.set('stdout', require('./stdout'));
coreAppenders.set('stderr', require('./stderr'));
coreAppenders.set('logLevelFilter', require('./logLevelFilter'));
coreAppenders.set('categoryFilter', require('./categoryFilter'));
coreAppenders.set('noLogFilter', require('./noLogFilter'));
coreAppenders.set('file', require('./file'));
coreAppenders.set('dateFile', require('./dateFile'));
coreAppenders.set('fileSync', require('./fileSync'));
coreAppenders.set('tcp', require('./tcp'));
const appenders = new Map();
const tryLoading = (modulePath, config) => {
let resolvedPath;
try {
const modulePathCJS = `${modulePath}.cjs`;
resolvedPath = require.resolve(modulePathCJS);
debug('Loading module from ', modulePathCJS);
} catch (e) {
resolvedPath = modulePath;
debug('Loading module from ', modulePath);
}
try {
// eslint-disable-next-line global-require, import/no-dynamic-require
return require(resolvedPath);
} catch (e) {
// if the module was found, and we still got an error, then raise it
configuration.throwExceptionIf(
config,
e.code !== 'MODULE_NOT_FOUND',
`appender "${modulePath}" could not be loaded (error was: ${e})`
);
return undefined;
}
};
const loadAppenderModule = (type, config) =>
coreAppenders.get(type) ||
tryLoading(`./${type}`, config) ||
tryLoading(type, config) ||
(require.main &&
require.main.filename &&
tryLoading(path.join(path.dirname(require.main.filename), type), config)) ||
tryLoading(path.join(process.cwd(), type), config);
const appendersLoading = new Set();
const getAppender = (name, config) => {
if (appenders.has(name)) return appenders.get(name);
if (!config.appenders[name]) return false;
if (appendersLoading.has(name))
throw new Error(`Dependency loop detected for appender ${name}.`);
appendersLoading.add(name);
debug(`Creating appender ${name}`);
// eslint-disable-next-line no-use-before-define
const appender = createAppender(name, config);
appendersLoading.delete(name);
appenders.set(name, appender);
return appender;
};
const createAppender = (name, config) => {
const appenderConfig = config.appenders[name];
const appenderModule = appenderConfig.type.configure
? appenderConfig.type
: loadAppenderModule(appenderConfig.type, config);
configuration.throwExceptionIf(
config,
configuration.not(appenderModule),
`appender "${name}" is not valid (type "${appenderConfig.type}" could not be found)`
);
if (appenderModule.appender) {
process.emitWarning(
`Appender ${appenderConfig.type} exports an appender function.`,
'DeprecationWarning',
'log4js-node-DEP0001'
);
debug(
'[log4js-node-DEP0001]',
`DEPRECATION: Appender ${appenderConfig.type} exports an appender function.`
);
}
if (appenderModule.shutdown) {
process.emitWarning(
`Appender ${appenderConfig.type} exports a shutdown function.`,
'DeprecationWarning',
'log4js-node-DEP0002'
);
debug(
'[log4js-node-DEP0002]',
`DEPRECATION: Appender ${appenderConfig.type} exports a shutdown function.`
);
}
debug(`${name}: clustering.isMaster ? ${clustering.isMaster()}`);
debug(
// eslint-disable-next-line global-require
`${name}: appenderModule is ${require('util').inspect(appenderModule)}`
);
return clustering.onlyOnMaster(
() => {
debug(
`calling appenderModule.configure for ${name} / ${appenderConfig.type}`
);
return appenderModule.configure(
adapters.modifyConfig(appenderConfig),
layouts,
(appender) => getAppender(appender, config),
levels
);
},
/* istanbul ignore next: fn never gets called by non-master yet needed to pass config validation */ () => {}
);
};
const setup = (config) => {
appenders.clear();
appendersLoading.clear();
if (!config) {
return;
}
const usedAppenders = [];
Object.values(config.categories).forEach((category) => {
usedAppenders.push(...category.appenders);
});
Object.keys(config.appenders).forEach((name) => {
// dodgy hard-coding of special case for tcp-server and multiprocess which may not have
// any categories associated with it, but needs to be started up anyway
if (
usedAppenders.includes(name) ||
config.appenders[name].type === 'tcp-server' ||
config.appenders[name].type === 'multiprocess'
) {
getAppender(name, config);
}
});
};
const init = () => {
setup();
};
init();
configuration.addListener((config) => {
configuration.throwExceptionIf(
config,
configuration.not(configuration.anObject(config.appenders)),
'must have a property "appenders" of type object.'
);
const appenderNames = Object.keys(config.appenders);
configuration.throwExceptionIf(
config,
configuration.not(appenderNames.length),
'must define at least one appender.'
);
appenderNames.forEach((name) => {
configuration.throwExceptionIf(
config,
configuration.not(config.appenders[name].type),
`appender "${name}" is not valid (must be an object with property "type")`
);
});
});
configuration.addListener(setup);
module.exports = appenders;
module.exports.init = init;

20
my-app/node_modules/log4js/lib/appenders/logLevelFilter.js generated vendored Executable file
View file

@ -0,0 +1,20 @@
function logLevelFilter(minLevelString, maxLevelString, appender, levels) {
const minLevel = levels.getLevel(minLevelString);
const maxLevel = levels.getLevel(maxLevelString, levels.FATAL);
return (logEvent) => {
const eventLevel = logEvent.level;
if (
minLevel.isLessThanOrEqualTo(eventLevel) &&
maxLevel.isGreaterThanOrEqualTo(eventLevel)
) {
appender(logEvent);
}
};
}
function configure(config, layouts, findAppender, levels) {
const appender = findAppender(config.appender);
return logLevelFilter(config.level, config.maxLevel, appender, levels);
}
module.exports.configure = configure;

91
my-app/node_modules/log4js/lib/appenders/multiFile.js generated vendored Executable file
View file

@ -0,0 +1,91 @@
const debug = require('debug')('log4js:multiFile');
const path = require('path');
const fileAppender = require('./file');
const findFileKey = (property, event) =>
event[property] || event.context[property];
module.exports.configure = (config, layouts) => {
debug('Creating a multi-file appender');
const files = new Map();
const timers = new Map();
function checkForTimeout(fileKey) {
const timer = timers.get(fileKey);
const app = files.get(fileKey);
/* istanbul ignore else: failsafe */
if (timer && app) {
if (Date.now() - timer.lastUsed > timer.timeout) {
debug('%s not used for > %d ms => close', fileKey, timer.timeout);
clearInterval(timer.interval);
timers.delete(fileKey);
files.delete(fileKey);
app.shutdown((err) => {
if (err) {
debug('ignore error on file shutdown: %s', err.message);
}
});
}
} else {
// will never get here as files and timers are coupled to be added and deleted at same place
debug('timer or app does not exist');
}
}
const appender = (logEvent) => {
const fileKey = findFileKey(config.property, logEvent);
debug('fileKey for property ', config.property, ' is ', fileKey);
if (fileKey) {
let file = files.get(fileKey);
debug('existing file appender is ', file);
if (!file) {
debug('creating new file appender');
config.filename = path.join(config.base, fileKey + config.extension);
file = fileAppender.configure(config, layouts);
files.set(fileKey, file);
if (config.timeout) {
debug('creating new timer');
timers.set(fileKey, {
timeout: config.timeout,
lastUsed: Date.now(),
interval: setInterval(
checkForTimeout.bind(null, fileKey),
config.timeout
),
});
}
} else if (config.timeout) {
debug('%s extending activity', fileKey);
timers.get(fileKey).lastUsed = Date.now();
}
file(logEvent);
} else {
debug('No fileKey for logEvent, quietly ignoring this log event');
}
};
appender.shutdown = (cb) => {
let shutdownFunctions = files.size;
if (shutdownFunctions <= 0) {
cb();
}
let error;
timers.forEach((timer, fileKey) => {
debug('clearing timer for ', fileKey);
clearInterval(timer.interval);
});
files.forEach((app, fileKey) => {
debug('calling shutdown for ', fileKey);
app.shutdown((err) => {
error = error || err;
shutdownFunctions -= 1;
if (shutdownFunctions <= 0) {
cb(error);
}
});
});
};
return appender;
};

191
my-app/node_modules/log4js/lib/appenders/multiprocess.js generated vendored Executable file
View file

@ -0,0 +1,191 @@
const debug = require('debug')('log4js:multiprocess');
const net = require('net');
const LoggingEvent = require('../LoggingEvent');
const END_MSG = '__LOG4JS__';
/**
* Creates a server, listening on config.loggerPort, config.loggerHost.
* Output goes to config.actualAppender (config.appender is used to
* set up that appender).
*/
function logServer(config, actualAppender, levels) {
/**
* Takes a utf-8 string, returns an object with
* the correct log properties.
*/
function deserializeLoggingEvent(clientSocket, msg) {
debug('(master) deserialising log event');
const loggingEvent = LoggingEvent.deserialise(msg);
loggingEvent.remoteAddress = clientSocket.remoteAddress;
loggingEvent.remotePort = clientSocket.remotePort;
return loggingEvent;
}
const server = net.createServer((clientSocket) => {
debug('(master) connection received');
clientSocket.setEncoding('utf8');
let logMessage = '';
function logTheMessage(msg) {
debug('(master) deserialising log event and sending to actual appender');
actualAppender(deserializeLoggingEvent(clientSocket, msg));
}
function chunkReceived(chunk) {
debug('(master) chunk of data received');
let event;
logMessage += chunk || '';
if (logMessage.indexOf(END_MSG) > -1) {
event = logMessage.slice(0, logMessage.indexOf(END_MSG));
logTheMessage(event);
logMessage = logMessage.slice(event.length + END_MSG.length) || '';
// check for more, maybe it was a big chunk
chunkReceived();
}
}
function handleError(error) {
const loggingEvent = {
startTime: new Date(),
categoryName: 'log4js',
level: levels.ERROR,
data: ['A worker log process hung up unexpectedly', error],
remoteAddress: clientSocket.remoteAddress,
remotePort: clientSocket.remotePort,
};
actualAppender(loggingEvent);
}
clientSocket.on('data', chunkReceived);
clientSocket.on('end', chunkReceived);
clientSocket.on('error', handleError);
});
server.listen(
config.loggerPort || 5000,
config.loggerHost || 'localhost',
(e) => {
debug('(master) master server listening, error was ', e);
// allow the process to exit, if this is the only socket active
server.unref();
}
);
function app(event) {
debug('(master) log event sent directly to actual appender (local event)');
return actualAppender(event);
}
app.shutdown = function (cb) {
debug('(master) master shutdown called, closing server');
server.close(cb);
};
return app;
}
function workerAppender(config) {
let canWrite = false;
const buffer = [];
let socket;
let shutdownAttempts = 3;
function write(loggingEvent) {
debug('(worker) Writing log event to socket');
socket.write(loggingEvent.serialise(), 'utf8');
socket.write(END_MSG, 'utf8');
}
function emptyBuffer() {
let evt;
debug('(worker) emptying worker buffer');
while ((evt = buffer.shift())) {
write(evt);
}
}
function createSocket() {
debug(
`(worker) worker appender creating socket to ${
config.loggerHost || 'localhost'
}:${config.loggerPort || 5000}`
);
socket = net.createConnection(
config.loggerPort || 5000,
config.loggerHost || 'localhost'
);
socket.on('connect', () => {
debug('(worker) worker socket connected');
emptyBuffer();
canWrite = true;
});
socket.on('timeout', socket.end.bind(socket));
socket.on('error', (e) => {
debug('connection error', e);
canWrite = false;
emptyBuffer();
});
socket.on('close', createSocket);
}
createSocket();
function log(loggingEvent) {
if (canWrite) {
write(loggingEvent);
} else {
debug(
'(worker) worker buffering log event because it cannot write at the moment'
);
buffer.push(loggingEvent);
}
}
log.shutdown = function (cb) {
debug('(worker) worker shutdown called');
if (buffer.length && shutdownAttempts) {
debug('(worker) worker buffer has items, waiting 100ms to empty');
shutdownAttempts -= 1;
setTimeout(() => {
log.shutdown(cb);
}, 100);
} else {
socket.removeAllListeners('close');
socket.end(cb);
}
};
return log;
}
function createAppender(config, appender, levels) {
if (config.mode === 'master') {
debug('Creating master appender');
return logServer(config, appender, levels);
}
debug('Creating worker appender');
return workerAppender(config);
}
function configure(config, layouts, findAppender, levels) {
let appender;
debug(`configure with mode = ${config.mode}`);
if (config.mode === 'master') {
if (!config.appender) {
debug(`no appender found in config ${config}`);
throw new Error('multiprocess master must have an "appender" defined');
}
debug(`actual appender is ${config.appender}`);
appender = findAppender(config.appender);
if (!appender) {
debug(`actual appender "${config.appender}" not found`);
throw new Error(
`multiprocess master appender "${config.appender}" not defined`
);
}
}
return createAppender(config, appender, levels);
}
module.exports.configure = configure;

43
my-app/node_modules/log4js/lib/appenders/noLogFilter.js generated vendored Executable file
View file

@ -0,0 +1,43 @@
const debug = require('debug')('log4js:noLogFilter');
/**
* The function removes empty or null regexp from the array
* @param {string[]} regexp
* @returns {string[]} a filtered string array with not empty or null regexp
*/
function removeNullOrEmptyRegexp(regexp) {
const filtered = regexp.filter((el) => el != null && el !== '');
return filtered;
}
/**
* Returns a function that will exclude the events in case they match
* with the regular expressions provided
* @param {(string|string[])} filters contains the regexp that will be used for the evaluation
* @param {*} appender
* @returns {function}
*/
function noLogFilter(filters, appender) {
return (logEvent) => {
debug(`Checking data: ${logEvent.data} against filters: ${filters}`);
if (typeof filters === 'string') {
filters = [filters];
}
filters = removeNullOrEmptyRegexp(filters);
const regex = new RegExp(filters.join('|'), 'i');
if (
filters.length === 0 ||
logEvent.data.findIndex((value) => regex.test(value)) < 0
) {
debug('Not excluded, sending to appender');
appender(logEvent);
}
};
}
function configure(config, layouts, findAppender) {
const appender = findAppender(config.appender);
return noLogFilter(config.exclude, appender);
}
module.exports.configure = configure;

29
my-app/node_modules/log4js/lib/appenders/recording.js generated vendored Executable file
View file

@ -0,0 +1,29 @@
const debug = require('debug')('log4js:recording');
const recordedEvents = [];
function configure() {
return function (logEvent) {
debug(
`received logEvent, number of events now ${recordedEvents.length + 1}`
);
debug('log event was ', logEvent);
recordedEvents.push(logEvent);
};
}
function replay() {
return recordedEvents.slice();
}
function reset() {
recordedEvents.length = 0;
}
module.exports = {
configure,
replay,
playback: replay,
reset,
erase: reset,
};

15
my-app/node_modules/log4js/lib/appenders/stderr.js generated vendored Executable file
View file

@ -0,0 +1,15 @@
function stderrAppender(layout, timezoneOffset) {
return (loggingEvent) => {
process.stderr.write(`${layout(loggingEvent, timezoneOffset)}\n`);
};
}
function configure(config, layouts) {
let layout = layouts.colouredLayout;
if (config.layout) {
layout = layouts.layout(config.layout.type, config.layout);
}
return stderrAppender(layout, config.timezoneOffset);
}
module.exports.configure = configure;

15
my-app/node_modules/log4js/lib/appenders/stdout.js generated vendored Executable file
View file

@ -0,0 +1,15 @@
function stdoutAppender(layout, timezoneOffset) {
return (loggingEvent) => {
process.stdout.write(`${layout(loggingEvent, timezoneOffset)}\n`);
};
}
function configure(config, layouts) {
let layout = layouts.colouredLayout;
if (config.layout) {
layout = layouts.layout(config.layout.type, config.layout);
}
return stdoutAppender(layout, config.timezoneOffset);
}
exports.configure = configure;

49
my-app/node_modules/log4js/lib/appenders/tcp-server.js generated vendored Executable file
View file

@ -0,0 +1,49 @@
const debug = require('debug')('log4js:tcp-server');
const net = require('net');
const clustering = require('../clustering');
const LoggingEvent = require('../LoggingEvent');
const DELIMITER = '__LOG4JS__';
exports.configure = (config) => {
debug('configure called with ', config);
const server = net.createServer((socket) => {
let dataSoFar = '';
const send = (data) => {
if (data) {
dataSoFar += data;
if (dataSoFar.indexOf(DELIMITER)) {
const events = dataSoFar.split(DELIMITER);
if (!dataSoFar.endsWith(DELIMITER)) {
dataSoFar = events.pop();
} else {
dataSoFar = '';
}
events
.filter((e) => e.length)
.forEach((e) => {
clustering.send(LoggingEvent.deserialise(e));
});
} else {
dataSoFar = '';
}
}
};
socket.setEncoding('utf8');
socket.on('data', send);
socket.on('end', send);
});
server.listen(config.port || 5000, config.host || 'localhost', () => {
debug(`listening on ${config.host || 'localhost'}:${config.port || 5000}`);
server.unref();
});
return {
shutdown: (cb) => {
debug('shutdown called.');
server.close(cb);
},
};
};

92
my-app/node_modules/log4js/lib/appenders/tcp.js generated vendored Executable file
View file

@ -0,0 +1,92 @@
const debug = require('debug')('log4js:tcp');
const net = require('net');
function appender(config, layout) {
let canWrite = false;
const buffer = [];
let socket;
let shutdownAttempts = 3;
let endMsg = '__LOG4JS__';
function write(loggingEvent) {
debug('Writing log event to socket');
canWrite = socket.write(`${layout(loggingEvent)}${endMsg}`, 'utf8');
}
function emptyBuffer() {
let evt;
debug('emptying buffer');
while ((evt = buffer.shift())) {
write(evt);
}
}
function createSocket() {
debug(
`appender creating socket to ${config.host || 'localhost'}:${
config.port || 5000
}`
);
endMsg = `${config.endMsg || '__LOG4JS__'}`;
socket = net.createConnection(
config.port || 5000,
config.host || 'localhost'
);
socket.on('connect', () => {
debug('socket connected');
emptyBuffer();
canWrite = true;
});
socket.on('drain', () => {
debug('drain event received, emptying buffer');
canWrite = true;
emptyBuffer();
});
socket.on('timeout', socket.end.bind(socket));
socket.on('error', (e) => {
debug('connection error', e);
canWrite = false;
emptyBuffer();
});
socket.on('close', createSocket);
}
createSocket();
function log(loggingEvent) {
if (canWrite) {
write(loggingEvent);
} else {
debug('buffering log event because it cannot write at the moment');
buffer.push(loggingEvent);
}
}
log.shutdown = function (cb) {
debug('shutdown called');
if (buffer.length && shutdownAttempts) {
debug('buffer has items, waiting 100ms to empty');
shutdownAttempts -= 1;
setTimeout(() => {
log.shutdown(cb);
}, 100);
} else {
socket.removeAllListeners('close');
socket.end(cb);
}
};
return log;
}
function configure(config, layouts) {
debug(`configure with config = ${config}`);
let layout = function (loggingEvent) {
return loggingEvent.serialise();
};
if (config.layout) {
layout = layouts.layout(config.layout.type, config.layout);
}
return appender(config, layout);
}
module.exports.configure = configure;

219
my-app/node_modules/log4js/lib/categories.js generated vendored Executable file
View file

@ -0,0 +1,219 @@
const debug = require('debug')('log4js:categories');
const configuration = require('./configuration');
const levels = require('./levels');
const appenders = require('./appenders');
const categories = new Map();
/**
* Add inherited config to this category. That includes extra appenders from parent,
* and level, if none is set on this category.
* This is recursive, so each parent also gets loaded with inherited appenders.
* Inheritance is blocked if a category has inherit=false
* @param {*} config
* @param {*} category the child category
* @param {string} categoryName dotted path to category
* @return {void}
*/
function inheritFromParent(config, category, categoryName) {
if (category.inherit === false) return;
const lastDotIndex = categoryName.lastIndexOf('.');
if (lastDotIndex < 0) return; // category is not a child
const parentCategoryName = categoryName.slice(0, lastDotIndex);
let parentCategory = config.categories[parentCategoryName];
if (!parentCategory) {
// parent is missing, so implicitly create it, so that it can inherit from its parents
parentCategory = { inherit: true, appenders: [] };
}
// make sure parent has had its inheritance taken care of before pulling its properties to this child
inheritFromParent(config, parentCategory, parentCategoryName);
// if the parent is not in the config (because we just created it above),
// and it inherited a valid configuration, add it to config.categories
if (
!config.categories[parentCategoryName] &&
parentCategory.appenders &&
parentCategory.appenders.length &&
parentCategory.level
) {
config.categories[parentCategoryName] = parentCategory;
}
category.appenders = category.appenders || [];
category.level = category.level || parentCategory.level;
// merge in appenders from parent (parent is already holding its inherited appenders)
parentCategory.appenders.forEach((ap) => {
if (!category.appenders.includes(ap)) {
category.appenders.push(ap);
}
});
category.parent = parentCategory;
}
/**
* Walk all categories in the config, and pull down any configuration from parent to child.
* This includes inherited appenders, and level, where level is not set.
* Inheritance is skipped where a category has inherit=false.
* @param {*} config
*/
function addCategoryInheritance(config) {
if (!config.categories) return;
const categoryNames = Object.keys(config.categories);
categoryNames.forEach((name) => {
const category = config.categories[name];
// add inherited appenders and level to this category
inheritFromParent(config, category, name);
});
}
configuration.addPreProcessingListener((config) =>
addCategoryInheritance(config)
);
configuration.addListener((config) => {
configuration.throwExceptionIf(
config,
configuration.not(configuration.anObject(config.categories)),
'must have a property "categories" of type object.'
);
const categoryNames = Object.keys(config.categories);
configuration.throwExceptionIf(
config,
configuration.not(categoryNames.length),
'must define at least one category.'
);
categoryNames.forEach((name) => {
const category = config.categories[name];
configuration.throwExceptionIf(
config,
[
configuration.not(category.appenders),
configuration.not(category.level),
],
`category "${name}" is not valid (must be an object with properties "appenders" and "level")`
);
configuration.throwExceptionIf(
config,
configuration.not(Array.isArray(category.appenders)),
`category "${name}" is not valid (appenders must be an array of appender names)`
);
configuration.throwExceptionIf(
config,
configuration.not(category.appenders.length),
`category "${name}" is not valid (appenders must contain at least one appender name)`
);
if (Object.prototype.hasOwnProperty.call(category, 'enableCallStack')) {
configuration.throwExceptionIf(
config,
typeof category.enableCallStack !== 'boolean',
`category "${name}" is not valid (enableCallStack must be boolean type)`
);
}
category.appenders.forEach((appender) => {
configuration.throwExceptionIf(
config,
configuration.not(appenders.get(appender)),
`category "${name}" is not valid (appender "${appender}" is not defined)`
);
});
configuration.throwExceptionIf(
config,
configuration.not(levels.getLevel(category.level)),
`category "${name}" is not valid (level "${category.level}" not recognised;` +
` valid levels are ${levels.levels.join(', ')})`
);
});
configuration.throwExceptionIf(
config,
configuration.not(config.categories.default),
'must define a "default" category.'
);
});
const setup = (config) => {
categories.clear();
if (!config) {
return;
}
const categoryNames = Object.keys(config.categories);
categoryNames.forEach((name) => {
const category = config.categories[name];
const categoryAppenders = [];
category.appenders.forEach((appender) => {
categoryAppenders.push(appenders.get(appender));
debug(`Creating category ${name}`);
categories.set(name, {
appenders: categoryAppenders,
level: levels.getLevel(category.level),
enableCallStack: category.enableCallStack || false,
});
});
});
};
const init = () => {
setup();
};
init();
configuration.addListener(setup);
const configForCategory = (category) => {
debug(`configForCategory: searching for config for ${category}`);
if (categories.has(category)) {
debug(`configForCategory: ${category} exists in config, returning it`);
return categories.get(category);
}
let sourceCategoryConfig;
if (category.indexOf('.') > 0) {
debug(`configForCategory: ${category} has hierarchy, cloning from parents`);
sourceCategoryConfig = {
...configForCategory(category.slice(0, category.lastIndexOf('.'))),
};
} else {
if (!categories.has('default')) {
setup({ categories: { default: { appenders: ['out'], level: 'OFF' } } });
}
debug('configForCategory: cloning default category');
sourceCategoryConfig = { ...categories.get('default') };
}
categories.set(category, sourceCategoryConfig);
return sourceCategoryConfig;
};
const appendersForCategory = (category) =>
configForCategory(category).appenders;
const getLevelForCategory = (category) => configForCategory(category).level;
const setLevelForCategory = (category, level) => {
configForCategory(category).level = level;
};
const getEnableCallStackForCategory = (category) =>
configForCategory(category).enableCallStack === true;
const setEnableCallStackForCategory = (category, useCallStack) => {
configForCategory(category).enableCallStack = useCallStack;
};
module.exports = categories;
module.exports = Object.assign(module.exports, {
appendersForCategory,
getLevelForCategory,
setLevelForCategory,
getEnableCallStackForCategory,
setEnableCallStackForCategory,
init,
});

105
my-app/node_modules/log4js/lib/clustering.js generated vendored Executable file
View file

@ -0,0 +1,105 @@
const debug = require('debug')('log4js:clustering');
const LoggingEvent = require('./LoggingEvent');
const configuration = require('./configuration');
let disabled = false;
let cluster = null;
try {
// eslint-disable-next-line global-require
cluster = require('cluster');
} catch (e) {
debug('cluster module not present');
disabled = true;
}
const listeners = [];
let pm2 = false;
let pm2InstanceVar = 'NODE_APP_INSTANCE';
const isPM2Master = () => pm2 && process.env[pm2InstanceVar] === '0';
const isMaster = () =>
disabled || (cluster && cluster.isMaster) || isPM2Master();
const sendToListeners = (logEvent) => {
listeners.forEach((l) => l(logEvent));
};
// in a multi-process node environment, worker loggers will use
// process.send
const receiver = (worker, message) => {
// prior to node v6, the worker parameter was not passed (args were message, handle)
debug('cluster message received from worker ', worker, ': ', message);
if (worker.topic && worker.data) {
message = worker;
worker = undefined;
}
if (message && message.topic && message.topic === 'log4js:message') {
debug('received message: ', message.data);
const logEvent = LoggingEvent.deserialise(message.data);
sendToListeners(logEvent);
}
};
if (!disabled) {
configuration.addListener((config) => {
// clear out the listeners, because configure has been called.
listeners.length = 0;
({
pm2,
disableClustering: disabled,
pm2InstanceVar = 'NODE_APP_INSTANCE',
} = config);
debug(`clustering disabled ? ${disabled}`);
debug(`cluster.isMaster ? ${cluster && cluster.isMaster}`);
debug(`pm2 enabled ? ${pm2}`);
debug(`pm2InstanceVar = ${pm2InstanceVar}`);
debug(`process.env[${pm2InstanceVar}] = ${process.env[pm2InstanceVar]}`);
// just in case configure is called after shutdown
if (pm2) {
process.removeListener('message', receiver);
}
if (cluster && cluster.removeListener) {
cluster.removeListener('message', receiver);
}
if (disabled || config.disableClustering) {
debug('Not listening for cluster messages, because clustering disabled.');
} else if (isPM2Master()) {
// PM2 cluster support
// PM2 runs everything as workers - install pm2-intercom for this to work.
// we only want one of the app instances to write logs
debug('listening for PM2 broadcast messages');
process.on('message', receiver);
} else if (cluster && cluster.isMaster) {
debug('listening for cluster messages');
cluster.on('message', receiver);
} else {
debug('not listening for messages, because we are not a master process');
}
});
}
module.exports = {
onlyOnMaster: (fn, notMaster) => (isMaster() ? fn() : notMaster),
isMaster,
send: (msg) => {
if (isMaster()) {
sendToListeners(msg);
} else {
if (!pm2) {
msg.cluster = {
workerId: cluster.worker.id,
worker: process.pid,
};
}
process.send({ topic: 'log4js:message', data: msg.serialise() });
}
},
onMessage: (listener) => {
listeners.push(listener);
},
};

19
my-app/node_modules/log4js/lib/clusteringBrowser.js generated vendored Executable file
View file

@ -0,0 +1,19 @@
/* istanbul ignore file */
// This is used in browsers only and is designed to allow the rest of
// log4js to continue as if `clustering.js` is in use.
const isMaster = () => true;
const listeners = [];
const sendToListeners = (logEvent) => {
listeners.forEach((l) => l(logEvent));
};
module.exports = {
onlyOnMaster: (fn, notMaster) => (isMaster() ? fn() : notMaster),
isMaster,
send: sendToListeners,
onMessage: (listener) => {
listeners.push(listener);
},
};

64
my-app/node_modules/log4js/lib/configuration.js generated vendored Executable file
View file

@ -0,0 +1,64 @@
const util = require('util');
const debug = require('debug')('log4js:configuration');
const preProcessingListeners = [];
const listeners = [];
const not = (thing) => !thing;
const anObject = (thing) =>
thing && typeof thing === 'object' && !Array.isArray(thing);
const validIdentifier = (thing) => /^[A-Za-z][A-Za-z0-9_]*$/g.test(thing);
const anInteger = (thing) =>
thing && typeof thing === 'number' && Number.isInteger(thing);
const addListener = (fn) => {
listeners.push(fn);
debug(`Added listener, now ${listeners.length} listeners`);
};
const addPreProcessingListener = (fn) => {
preProcessingListeners.push(fn);
debug(
`Added pre-processing listener, now ${preProcessingListeners.length} listeners`
);
};
const throwExceptionIf = (config, checks, message) => {
const tests = Array.isArray(checks) ? checks : [checks];
tests.forEach((test) => {
if (test) {
throw new Error(
`Problem with log4js configuration: (${util.inspect(config, {
depth: 5,
})}) - ${message}`
);
}
});
};
const configure = (candidate) => {
debug('New configuration to be validated: ', candidate);
throwExceptionIf(candidate, not(anObject(candidate)), 'must be an object.');
debug(`Calling pre-processing listeners (${preProcessingListeners.length})`);
preProcessingListeners.forEach((listener) => listener(candidate));
debug('Configuration pre-processing finished.');
debug(`Calling configuration listeners (${listeners.length})`);
listeners.forEach((listener) => listener(candidate));
debug('Configuration finished.');
};
module.exports = {
configure,
addListener,
addPreProcessingListener,
throwExceptionIf,
anObject,
anInteger,
validIdentifier,
not,
};

323
my-app/node_modules/log4js/lib/connect-logger.js generated vendored Executable file
View file

@ -0,0 +1,323 @@
/* eslint no-underscore-dangle: ["error", { "allow": ["__statusCode", "_remoteAddress", "__headers", "_logging"] }] */
const levels = require('./levels');
const DEFAULT_FORMAT =
':remote-addr - -' +
' ":method :url HTTP/:http-version"' +
' :status :content-length ":referrer"' +
' ":user-agent"';
/**
* Return request url path,
* adding this function prevents the Cyclomatic Complexity,
* for the assemble_tokens function at low, to pass the tests.
*
* @param {IncomingMessage} req
* @return {string}
* @api private
*/
function getUrl(req) {
return req.originalUrl || req.url;
}
/**
* Adds custom {token, replacement} objects to defaults,
* overwriting the defaults if any tokens clash
*
* @param {IncomingMessage} req
* @param {ServerResponse} res
* @param {Array} customTokens
* [{ token: string-or-regexp, replacement: string-or-replace-function }]
* @return {Array}
*/
function assembleTokens(req, res, customTokens) {
const arrayUniqueTokens = (array) => {
const a = array.concat();
for (let i = 0; i < a.length; ++i) {
for (let j = i + 1; j < a.length; ++j) {
// not === because token can be regexp object
// eslint-disable-next-line eqeqeq
if (a[i].token == a[j].token) {
a.splice(j--, 1); // eslint-disable-line no-plusplus
}
}
}
return a;
};
const defaultTokens = [];
defaultTokens.push({ token: ':url', replacement: getUrl(req) });
defaultTokens.push({ token: ':protocol', replacement: req.protocol });
defaultTokens.push({ token: ':hostname', replacement: req.hostname });
defaultTokens.push({ token: ':method', replacement: req.method });
defaultTokens.push({
token: ':status',
replacement: res.__statusCode || res.statusCode,
});
defaultTokens.push({
token: ':response-time',
replacement: res.responseTime,
});
defaultTokens.push({ token: ':date', replacement: new Date().toUTCString() });
defaultTokens.push({
token: ':referrer',
replacement: req.headers.referer || req.headers.referrer || '',
});
defaultTokens.push({
token: ':http-version',
replacement: `${req.httpVersionMajor}.${req.httpVersionMinor}`,
});
defaultTokens.push({
token: ':remote-addr',
replacement:
req.headers['x-forwarded-for'] ||
req.ip ||
req._remoteAddress ||
(req.socket &&
(req.socket.remoteAddress ||
(req.socket.socket && req.socket.socket.remoteAddress))),
});
defaultTokens.push({
token: ':user-agent',
replacement: req.headers['user-agent'],
});
defaultTokens.push({
token: ':content-length',
replacement:
res.getHeader('content-length') ||
(res.__headers && res.__headers['Content-Length']) ||
'-',
});
defaultTokens.push({
token: /:req\[([^\]]+)]/g,
replacement(_, field) {
return req.headers[field.toLowerCase()];
},
});
defaultTokens.push({
token: /:res\[([^\]]+)]/g,
replacement(_, field) {
return (
res.getHeader(field.toLowerCase()) ||
(res.__headers && res.__headers[field])
);
},
});
return arrayUniqueTokens(customTokens.concat(defaultTokens));
}
/**
* Return formatted log line.
*
* @param {string} str
* @param {Array} tokens
* @return {string}
* @api private
*/
function format(str, tokens) {
for (let i = 0; i < tokens.length; i++) {
str = str.replace(tokens[i].token, tokens[i].replacement);
}
return str;
}
/**
* Return RegExp Object about nolog
*
* @param {(string|Array)} nolog
* @return {RegExp}
* @api private
*
* syntax
* 1. String
* 1.1 "\\.gif"
* NOT LOGGING http://example.com/hoge.gif and http://example.com/hoge.gif?fuga
* LOGGING http://example.com/hoge.agif
* 1.2 in "\\.gif|\\.jpg$"
* NOT LOGGING http://example.com/hoge.gif and
* http://example.com/hoge.gif?fuga and http://example.com/hoge.jpg?fuga
* LOGGING http://example.com/hoge.agif,
* http://example.com/hoge.ajpg and http://example.com/hoge.jpg?hoge
* 1.3 in "\\.(gif|jpe?g|png)$"
* NOT LOGGING http://example.com/hoge.gif and http://example.com/hoge.jpeg
* LOGGING http://example.com/hoge.gif?uid=2 and http://example.com/hoge.jpg?pid=3
* 2. RegExp
* 2.1 in /\.(gif|jpe?g|png)$/
* SAME AS 1.3
* 3. Array
* 3.1 ["\\.jpg$", "\\.png", "\\.gif"]
* SAME AS "\\.jpg|\\.png|\\.gif"
*/
function createNoLogCondition(nolog) {
let regexp = null;
if (nolog instanceof RegExp) {
regexp = nolog;
}
if (typeof nolog === 'string') {
regexp = new RegExp(nolog);
}
if (Array.isArray(nolog)) {
// convert to strings
const regexpsAsStrings = nolog.map((reg) =>
reg.source ? reg.source : reg
);
regexp = new RegExp(regexpsAsStrings.join('|'));
}
return regexp;
}
/**
* Allows users to define rules around status codes to assign them to a specific
* logging level.
* There are two types of rules:
* - RANGE: matches a code within a certain range
* E.g. { 'from': 200, 'to': 299, 'level': 'info' }
* - CONTAINS: matches a code to a set of expected codes
* E.g. { 'codes': [200, 203], 'level': 'debug' }
* Note*: Rules are respected only in order of prescendence.
*
* @param {Number} statusCode
* @param {Level} currentLevel
* @param {Object} ruleSet
* @return {Level}
* @api private
*/
function matchRules(statusCode, currentLevel, ruleSet) {
let level = currentLevel;
if (ruleSet) {
const matchedRule = ruleSet.find((rule) => {
let ruleMatched = false;
if (rule.from && rule.to) {
ruleMatched = statusCode >= rule.from && statusCode <= rule.to;
} else {
ruleMatched = rule.codes.indexOf(statusCode) !== -1;
}
return ruleMatched;
});
if (matchedRule) {
level = levels.getLevel(matchedRule.level, level);
}
}
return level;
}
/**
* Log requests with the given `options` or a `format` string.
*
* Options:
*
* - `format` Format string, see below for tokens
* - `level` A log4js levels instance. Supports also 'auto'
* - `nolog` A string or RegExp to exclude target logs or function(req, res): boolean
* - `statusRules` A array of rules for setting specific logging levels base on status codes
* - `context` Whether to add a response of express to the context
*
* Tokens:
*
* - `:req[header]` ex: `:req[Accept]`
* - `:res[header]` ex: `:res[Content-Length]`
* - `:http-version`
* - `:response-time`
* - `:remote-addr`
* - `:date`
* - `:method`
* - `:url`
* - `:referrer`
* - `:user-agent`
* - `:status`
*
* @return {Function}
* @param logger4js
* @param options
* @api public
*/
module.exports = function getLogger(logger4js, options) {
if (typeof options === 'string' || typeof options === 'function') {
options = { format: options };
} else {
options = options || {};
}
const thisLogger = logger4js;
let level = levels.getLevel(options.level, levels.INFO);
const fmt = options.format || DEFAULT_FORMAT;
return (req, res, next) => {
// mount safety
if (typeof req._logging !== 'undefined') return next();
// nologs
if (typeof options.nolog !== 'function') {
const nolog = createNoLogCondition(options.nolog);
if (nolog && nolog.test(req.originalUrl)) return next();
}
if (thisLogger.isLevelEnabled(level) || options.level === 'auto') {
const start = new Date();
const { writeHead } = res;
// flag as logging
req._logging = true;
// proxy for statusCode.
res.writeHead = (code, headers) => {
res.writeHead = writeHead;
res.writeHead(code, headers);
res.__statusCode = code;
res.__headers = headers || {};
};
// hook on end request to emit the log entry of the HTTP request.
let finished = false;
const handler = () => {
if (finished) {
return;
}
finished = true;
// nologs
if (typeof options.nolog === 'function') {
if (options.nolog(req, res) === true) {
req._logging = false;
return;
}
}
res.responseTime = new Date() - start;
// status code response level handling
if (res.statusCode && options.level === 'auto') {
level = levels.INFO;
if (res.statusCode >= 300) level = levels.WARN;
if (res.statusCode >= 400) level = levels.ERROR;
}
level = matchRules(res.statusCode, level, options.statusRules);
const combinedTokens = assembleTokens(req, res, options.tokens || []);
if (options.context) thisLogger.addContext('res', res);
if (typeof fmt === 'function') {
const line = fmt(req, res, (str) => format(str, combinedTokens));
if (line) thisLogger.log(level, line);
} else {
thisLogger.log(level, format(fmt, combinedTokens));
}
if (options.context) thisLogger.removeContext('res');
};
res.on('end', handler);
res.on('finish', handler);
res.on('error', handler);
res.on('close', handler);
}
// ensure next gets always called
return next();
};
};

486
my-app/node_modules/log4js/lib/layouts.js generated vendored Executable file
View file

@ -0,0 +1,486 @@
const dateFormat = require('date-format');
const os = require('os');
const util = require('util');
const path = require('path');
const url = require('url');
const debug = require('debug')('log4js:layouts');
const styles = {
// styles
bold: [1, 22],
italic: [3, 23],
underline: [4, 24],
inverse: [7, 27],
// grayscale
white: [37, 39],
grey: [90, 39],
black: [90, 39],
// colors
blue: [34, 39],
cyan: [36, 39],
green: [32, 39],
magenta: [35, 39],
red: [91, 39],
yellow: [33, 39],
};
function colorizeStart(style) {
return style ? `\x1B[${styles[style][0]}m` : '';
}
function colorizeEnd(style) {
return style ? `\x1B[${styles[style][1]}m` : '';
}
/**
* Taken from masylum's fork (https://github.com/masylum/log4js-node)
*/
function colorize(str, style) {
return colorizeStart(style) + str + colorizeEnd(style);
}
function timestampLevelAndCategory(loggingEvent, colour) {
return colorize(
util.format(
'[%s] [%s] %s - ',
dateFormat.asString(loggingEvent.startTime),
loggingEvent.level.toString(),
loggingEvent.categoryName
),
colour
);
}
/**
* BasicLayout is a simple layout for storing the logs. The logs are stored
* in following format:
* <pre>
* [startTime] [logLevel] categoryName - message\n
* </pre>
*
* @author Stephan Strittmatter
*/
function basicLayout(loggingEvent) {
return (
timestampLevelAndCategory(loggingEvent) + util.format(...loggingEvent.data)
);
}
/**
* colouredLayout - taken from masylum's fork.
* same as basicLayout, but with colours.
*/
function colouredLayout(loggingEvent) {
return (
timestampLevelAndCategory(loggingEvent, loggingEvent.level.colour) +
util.format(...loggingEvent.data)
);
}
function messagePassThroughLayout(loggingEvent) {
return util.format(...loggingEvent.data);
}
function dummyLayout(loggingEvent) {
return loggingEvent.data[0];
}
/**
* PatternLayout
* Format for specifiers is %[padding].[truncation][field]{[format]}
* e.g. %5.10p - left pad the log level by 5 characters, up to a max of 10
* both padding and truncation can be negative.
* Negative truncation = trunc from end of string
* Positive truncation = trunc from start of string
* Negative padding = pad right
* Positive padding = pad left
*
* Fields can be any of:
* - %r time in toLocaleTimeString format
* - %p log level
* - %c log category
* - %h hostname
* - %m log data
* - %m{l} where l is an integer, log data.slice(l)
* - %m{l,u} where l and u are integers, log data.slice(l, u)
* - %d date in constious formats
* - %% %
* - %n newline
* - %z pid
* - %f filename
* - %l line number
* - %o column postion
* - %s call stack
* - %C class name [#1316](https://github.com/log4js-node/log4js-node/pull/1316)
* - %M method or function name [#1316](https://github.com/log4js-node/log4js-node/pull/1316)
* - %A method or function alias [#1316](https://github.com/log4js-node/log4js-node/pull/1316)
* - %F fully qualified caller name [#1316](https://github.com/log4js-node/log4js-node/pull/1316)
* - %x{<tokenname>} add dynamic tokens to your log. Tokens are specified in the tokens parameter
* - %X{<tokenname>} add dynamic tokens to your log. Tokens are specified in logger context
* You can use %[ and %] to define a colored block.
*
* Tokens are specified as simple key:value objects.
* The key represents the token name whereas the value can be a string or function
* which is called to extract the value to put in the log message. If token is not
* found, it doesn't replace the field.
*
* A sample token would be: { 'pid' : function() { return process.pid; } }
*
* Takes a pattern string, array of tokens and returns a layout function.
* @return {Function}
* @param pattern
* @param tokens
* @param timezoneOffset
*
* @authors ['Stephan Strittmatter', 'Jan Schmidle']
*/
function patternLayout(pattern, tokens) {
const TTCC_CONVERSION_PATTERN = '%r %p %c - %m%n';
const regex =
/%(-?[0-9]+)?(\.?-?[0-9]+)?([[\]cdhmnprzxXyflosCMAF%])(\{([^}]+)\})?|([^%]+)/;
pattern = pattern || TTCC_CONVERSION_PATTERN;
function categoryName(loggingEvent, specifier) {
let loggerName = loggingEvent.categoryName;
if (specifier) {
const precision = parseInt(specifier, 10);
const loggerNameBits = loggerName.split('.');
if (precision < loggerNameBits.length) {
loggerName = loggerNameBits
.slice(loggerNameBits.length - precision)
.join('.');
}
}
return loggerName;
}
function formatAsDate(loggingEvent, specifier) {
let format = dateFormat.ISO8601_FORMAT;
if (specifier) {
format = specifier;
// Pick up special cases
switch (format) {
case 'ISO8601':
case 'ISO8601_FORMAT':
format = dateFormat.ISO8601_FORMAT;
break;
case 'ISO8601_WITH_TZ_OFFSET':
case 'ISO8601_WITH_TZ_OFFSET_FORMAT':
format = dateFormat.ISO8601_WITH_TZ_OFFSET_FORMAT;
break;
case 'ABSOLUTE':
process.emitWarning(
'Pattern %d{ABSOLUTE} is deprecated in favor of %d{ABSOLUTETIME}. ' +
'Please use %d{ABSOLUTETIME} instead.',
'DeprecationWarning',
'log4js-node-DEP0003'
);
debug(
'[log4js-node-DEP0003]',
'DEPRECATION: Pattern %d{ABSOLUTE} is deprecated and replaced by %d{ABSOLUTETIME}.'
);
// falls through
case 'ABSOLUTETIME':
case 'ABSOLUTETIME_FORMAT':
format = dateFormat.ABSOLUTETIME_FORMAT;
break;
case 'DATE':
process.emitWarning(
'Pattern %d{DATE} is deprecated due to the confusion it causes when used. ' +
'Please use %d{DATETIME} instead.',
'DeprecationWarning',
'log4js-node-DEP0004'
);
debug(
'[log4js-node-DEP0004]',
'DEPRECATION: Pattern %d{DATE} is deprecated and replaced by %d{DATETIME}.'
);
// falls through
case 'DATETIME':
case 'DATETIME_FORMAT':
format = dateFormat.DATETIME_FORMAT;
break;
// no default
}
}
// Format the date
return dateFormat.asString(format, loggingEvent.startTime);
}
function hostname() {
return os.hostname().toString();
}
function formatMessage(loggingEvent, specifier) {
let dataSlice = loggingEvent.data;
if (specifier) {
const [lowerBound, upperBound] = specifier.split(',');
dataSlice = dataSlice.slice(lowerBound, upperBound);
}
return util.format(...dataSlice);
}
function endOfLine() {
return os.EOL;
}
function logLevel(loggingEvent) {
return loggingEvent.level.toString();
}
function startTime(loggingEvent) {
return dateFormat.asString('hh:mm:ss', loggingEvent.startTime);
}
function startColour(loggingEvent) {
return colorizeStart(loggingEvent.level.colour);
}
function endColour(loggingEvent) {
return colorizeEnd(loggingEvent.level.colour);
}
function percent() {
return '%';
}
function pid(loggingEvent) {
return loggingEvent && loggingEvent.pid
? loggingEvent.pid.toString()
: process.pid.toString();
}
function clusterInfo() {
// this used to try to return the master and worker pids,
// but it would never have worked because master pid is not available to workers
// leaving this here to maintain compatibility for patterns
return pid();
}
function userDefined(loggingEvent, specifier) {
if (typeof tokens[specifier] !== 'undefined') {
return typeof tokens[specifier] === 'function'
? tokens[specifier](loggingEvent)
: tokens[specifier];
}
return null;
}
function contextDefined(loggingEvent, specifier) {
const resolver = loggingEvent.context[specifier];
if (typeof resolver !== 'undefined') {
return typeof resolver === 'function' ? resolver(loggingEvent) : resolver;
}
return null;
}
function fileName(loggingEvent, specifier) {
let filename = loggingEvent.fileName || '';
// support for ESM as it uses url instead of path for file
/* istanbul ignore next: unsure how to simulate ESM for test coverage */
const convertFileURLToPath = function (filepath) {
const urlPrefix = 'file://';
if (filepath.startsWith(urlPrefix)) {
// https://nodejs.org/api/url.html#urlfileurltopathurl
if (typeof url.fileURLToPath === 'function') {
filepath = url.fileURLToPath(filepath);
}
// backward-compatible for nodejs pre-10.12.0 (without url.fileURLToPath method)
else {
// posix: file:///hello/world/foo.txt -> /hello/world/foo.txt -> /hello/world/foo.txt
// win32: file:///C:/path/foo.txt -> /C:/path/foo.txt -> \C:\path\foo.txt -> C:\path\foo.txt
// win32: file://nas/foo.txt -> //nas/foo.txt -> nas\foo.txt -> \\nas\foo.txt
filepath = path.normalize(
filepath.replace(new RegExp(`^${urlPrefix}`), '')
);
if (process.platform === 'win32') {
if (filepath.startsWith('\\')) {
filepath = filepath.slice(1);
} else {
filepath = path.sep + path.sep + filepath;
}
}
}
}
return filepath;
};
filename = convertFileURLToPath(filename);
if (specifier) {
const fileDepth = parseInt(specifier, 10);
const fileList = filename.split(path.sep);
if (fileList.length > fileDepth) {
filename = fileList.slice(-fileDepth).join(path.sep);
}
}
return filename;
}
function lineNumber(loggingEvent) {
return loggingEvent.lineNumber ? `${loggingEvent.lineNumber}` : '';
}
function columnNumber(loggingEvent) {
return loggingEvent.columnNumber ? `${loggingEvent.columnNumber}` : '';
}
function callStack(loggingEvent) {
return loggingEvent.callStack || '';
}
function className(loggingEvent) {
return loggingEvent.className || '';
}
function functionName(loggingEvent) {
return loggingEvent.functionName || '';
}
function functionAlias(loggingEvent) {
return loggingEvent.functionAlias || '';
}
function callerName(loggingEvent) {
return loggingEvent.callerName || '';
}
const replacers = {
c: categoryName,
d: formatAsDate,
h: hostname,
m: formatMessage,
n: endOfLine,
p: logLevel,
r: startTime,
'[': startColour,
']': endColour,
y: clusterInfo,
z: pid,
'%': percent,
x: userDefined,
X: contextDefined,
f: fileName,
l: lineNumber,
o: columnNumber,
s: callStack,
C: className,
M: functionName,
A: functionAlias,
F: callerName,
};
function replaceToken(conversionCharacter, loggingEvent, specifier) {
return replacers[conversionCharacter](loggingEvent, specifier);
}
function truncate(truncation, toTruncate) {
let len;
if (truncation) {
len = parseInt(truncation.slice(1), 10);
// negative truncate length means truncate from end of string
return len > 0 ? toTruncate.slice(0, len) : toTruncate.slice(len);
}
return toTruncate;
}
function pad(padding, toPad) {
let len;
if (padding) {
if (padding.charAt(0) === '-') {
len = parseInt(padding.slice(1), 10);
// Right pad with spaces
while (toPad.length < len) {
toPad += ' ';
}
} else {
len = parseInt(padding, 10);
// Left pad with spaces
while (toPad.length < len) {
toPad = ` ${toPad}`;
}
}
}
return toPad;
}
function truncateAndPad(toTruncAndPad, truncation, padding) {
let replacement = toTruncAndPad;
replacement = truncate(truncation, replacement);
replacement = pad(padding, replacement);
return replacement;
}
return function (loggingEvent) {
let formattedString = '';
let result;
let searchString = pattern;
while ((result = regex.exec(searchString)) !== null) {
// const matchedString = result[0];
const padding = result[1];
const truncation = result[2];
const conversionCharacter = result[3];
const specifier = result[5];
const text = result[6];
// Check if the pattern matched was just normal text
if (text) {
formattedString += text.toString();
} else {
// Create a raw replacement string based on the conversion
// character and specifier
const replacement = replaceToken(
conversionCharacter,
loggingEvent,
specifier
);
formattedString += truncateAndPad(replacement, truncation, padding);
}
searchString = searchString.slice(result.index + result[0].length);
}
return formattedString;
};
}
const layoutMakers = {
messagePassThrough() {
return messagePassThroughLayout;
},
basic() {
return basicLayout;
},
colored() {
return colouredLayout;
},
coloured() {
return colouredLayout;
},
pattern(config) {
return patternLayout(config && config.pattern, config && config.tokens);
},
dummy() {
return dummyLayout;
},
};
module.exports = {
basicLayout,
messagePassThroughLayout,
patternLayout,
colouredLayout,
coloredLayout: colouredLayout,
dummyLayout,
addLayout(name, serializerGenerator) {
layoutMakers[name] = serializerGenerator;
},
layout(name, config) {
return layoutMakers[name] && layoutMakers[name](config);
},
};

155
my-app/node_modules/log4js/lib/levels.js generated vendored Executable file
View file

@ -0,0 +1,155 @@
const configuration = require('./configuration');
const validColours = [
'white',
'grey',
'black',
'blue',
'cyan',
'green',
'magenta',
'red',
'yellow',
];
class Level {
constructor(level, levelStr, colour) {
this.level = level;
this.levelStr = levelStr;
this.colour = colour;
}
toString() {
return this.levelStr;
}
/**
* converts given String to corresponding Level
* @param {(Level|string)} sArg -- String value of Level OR Log4js.Level
* @param {Level} [defaultLevel] -- default Level, if no String representation
* @return {Level}
*/
static getLevel(sArg, defaultLevel) {
if (!sArg) {
return defaultLevel;
}
if (sArg instanceof Level) {
return sArg;
}
// a json-serialised level won't be an instance of Level (see issue #768)
if (sArg instanceof Object && sArg.levelStr) {
sArg = sArg.levelStr;
}
return Level[sArg.toString().toUpperCase()] || defaultLevel;
}
static addLevels(customLevels) {
if (customLevels) {
const levels = Object.keys(customLevels);
levels.forEach((l) => {
const levelStr = l.toUpperCase();
Level[levelStr] = new Level(
customLevels[l].value,
levelStr,
customLevels[l].colour
);
const existingLevelIndex = Level.levels.findIndex(
(lvl) => lvl.levelStr === levelStr
);
if (existingLevelIndex > -1) {
Level.levels[existingLevelIndex] = Level[levelStr];
} else {
Level.levels.push(Level[levelStr]);
}
});
Level.levels.sort((a, b) => a.level - b.level);
}
}
isLessThanOrEqualTo(otherLevel) {
if (typeof otherLevel === 'string') {
otherLevel = Level.getLevel(otherLevel);
}
return this.level <= otherLevel.level;
}
isGreaterThanOrEqualTo(otherLevel) {
if (typeof otherLevel === 'string') {
otherLevel = Level.getLevel(otherLevel);
}
return this.level >= otherLevel.level;
}
isEqualTo(otherLevel) {
if (typeof otherLevel === 'string') {
otherLevel = Level.getLevel(otherLevel);
}
return this.level === otherLevel.level;
}
}
Level.levels = [];
Level.addLevels({
ALL: { value: Number.MIN_VALUE, colour: 'grey' },
TRACE: { value: 5000, colour: 'blue' },
DEBUG: { value: 10000, colour: 'cyan' },
INFO: { value: 20000, colour: 'green' },
WARN: { value: 30000, colour: 'yellow' },
ERROR: { value: 40000, colour: 'red' },
FATAL: { value: 50000, colour: 'magenta' },
MARK: { value: 9007199254740992, colour: 'grey' }, // 2^53
OFF: { value: Number.MAX_VALUE, colour: 'grey' },
});
configuration.addListener((config) => {
const levelConfig = config.levels;
if (levelConfig) {
configuration.throwExceptionIf(
config,
configuration.not(configuration.anObject(levelConfig)),
'levels must be an object'
);
const newLevels = Object.keys(levelConfig);
newLevels.forEach((l) => {
configuration.throwExceptionIf(
config,
configuration.not(configuration.validIdentifier(l)),
`level name "${l}" is not a valid identifier (must start with a letter, only contain A-Z,a-z,0-9,_)`
);
configuration.throwExceptionIf(
config,
configuration.not(configuration.anObject(levelConfig[l])),
`level "${l}" must be an object`
);
configuration.throwExceptionIf(
config,
configuration.not(levelConfig[l].value),
`level "${l}" must have a 'value' property`
);
configuration.throwExceptionIf(
config,
configuration.not(configuration.anInteger(levelConfig[l].value)),
`level "${l}".value must have an integer value`
);
configuration.throwExceptionIf(
config,
configuration.not(levelConfig[l].colour),
`level "${l}" must have a 'colour' property`
);
configuration.throwExceptionIf(
config,
configuration.not(validColours.indexOf(levelConfig[l].colour) > -1),
`level "${l}".colour must be one of ${validColours.join(', ')}`
);
});
}
});
configuration.addListener((config) => {
Level.addLevels(config.levels);
});
module.exports = Level;

186
my-app/node_modules/log4js/lib/log4js.js generated vendored Executable file
View file

@ -0,0 +1,186 @@
/**
* @fileoverview log4js is a library to log in JavaScript in similar manner
* than in log4j for Java (but not really).
*
* <h3>Example:</h3>
* <pre>
* const logging = require('log4js');
* const log = logging.getLogger('some-category');
*
* //call the log
* log.trace('trace me' );
* </pre>
*
* NOTE: the authors below are the original browser-based log4js authors
* don't try to contact them about bugs in this version :)
* @author Stephan Strittmatter - http://jroller.com/page/stritti
* @author Seth Chisamore - http://www.chisamore.com
* @since 2005-05-20
* Website: http://log4js.berlios.de
*/
const debug = require('debug')('log4js:main');
const fs = require('fs');
const deepClone = require('rfdc')({ proto: true });
const configuration = require('./configuration');
const layouts = require('./layouts');
const levels = require('./levels');
const appenders = require('./appenders');
const categories = require('./categories');
const Logger = require('./logger');
const clustering = require('./clustering');
const connectLogger = require('./connect-logger');
const recordingModule = require('./appenders/recording');
let enabled = false;
function sendLogEventToAppender(logEvent) {
if (!enabled) return;
debug('Received log event ', logEvent);
const categoryAppenders = categories.appendersForCategory(
logEvent.categoryName
);
categoryAppenders.forEach((appender) => {
appender(logEvent);
});
}
function loadConfigurationFile(filename) {
debug(`Loading configuration from ${filename}`);
try {
return JSON.parse(fs.readFileSync(filename, 'utf8'));
} catch (e) {
throw new Error(
`Problem reading config from file "${filename}". Error was ${e.message}`,
e
);
}
}
function configure(configurationFileOrObject) {
if (enabled) {
// eslint-disable-next-line no-use-before-define
shutdown();
}
let configObject = configurationFileOrObject;
if (typeof configObject === 'string') {
configObject = loadConfigurationFile(configurationFileOrObject);
}
debug(`Configuration is ${configObject}`);
configuration.configure(deepClone(configObject));
clustering.onMessage(sendLogEventToAppender);
enabled = true;
// eslint-disable-next-line no-use-before-define
return log4js;
}
function isConfigured() {
return enabled;
}
function recording() {
return recordingModule;
}
/**
* This callback type is called `shutdownCallback` and is displayed as a global symbol.
*
* @callback shutdownCallback
* @param {Error} [error]
*/
/**
* Shutdown all log appenders. This will first disable all writing to appenders
* and then call the shutdown function each appender.
*
* @param {shutdownCallback} [callback] - The callback to be invoked once all appenders have
* shutdown. If an error occurs, the callback will be given the error object
* as the first argument.
*/
function shutdown(callback = () => {}) {
if (typeof callback !== 'function') {
throw new TypeError('Invalid callback passed to shutdown');
}
debug('Shutdown called. Disabling all log writing.');
// First, disable all writing to appenders. This prevents appenders from
// not being able to be drained because of run-away log writes.
enabled = false;
// Clone out to maintain a reference
const appendersToCheck = Array.from(appenders.values());
// Reset immediately to prevent leaks
appenders.init();
categories.init();
// Count the number of shutdown functions
const shutdownFunctions = appendersToCheck.reduce(
(accum, next) => (next.shutdown ? accum + 1 : accum),
0
);
if (shutdownFunctions === 0) {
debug('No appenders with shutdown functions found.');
callback();
}
let completed = 0;
let error;
debug(`Found ${shutdownFunctions} appenders with shutdown functions.`);
function complete(err) {
error = error || err;
completed += 1;
debug(`Appender shutdowns complete: ${completed} / ${shutdownFunctions}`);
if (completed >= shutdownFunctions) {
debug('All shutdown functions completed.');
callback(error);
}
}
// Call each of the shutdown functions
appendersToCheck
.filter((a) => a.shutdown)
.forEach((a) => a.shutdown(complete));
}
/**
* Get a logger instance.
* @static
* @param {string} [category=default]
* @return {Logger} instance of logger for the category
*/
function getLogger(category) {
if (!enabled) {
configure(
process.env.LOG4JS_CONFIG || {
appenders: { out: { type: 'stdout' } },
categories: { default: { appenders: ['out'], level: 'OFF' } },
}
);
}
return new Logger(category || 'default');
}
/**
* @name log4js
* @namespace Log4js
* @property getLogger
* @property configure
* @property shutdown
*/
const log4js = {
getLogger,
configure,
isConfigured,
shutdown,
connectLogger,
levels,
addLayout: layouts.addLayout,
recording,
};
module.exports = log4js;

245
my-app/node_modules/log4js/lib/logger.js generated vendored Executable file
View file

@ -0,0 +1,245 @@
/* eslint no-underscore-dangle: ["error", { "allow": ["_log"] }] */
const debug = require('debug')('log4js:logger');
const LoggingEvent = require('./LoggingEvent');
const levels = require('./levels');
const clustering = require('./clustering');
const categories = require('./categories');
const configuration = require('./configuration');
const stackReg = /^(?:\s*)at (?:(.+) \()?(?:([^(]+?):(\d+):(\d+))\)?$/;
/**
* The top entry is the Error
*/
const baseCallStackSkip = 1;
/**
* The _log function is 3 levels deep, we need to skip those to make it to the callSite
*/
const defaultErrorCallStackSkip = 3;
/**
*
* @param {Error} data
* @param {number} skipIdx
* @returns {import('../types/log4js').CallStack | null}
*/
function defaultParseCallStack(
data,
skipIdx = defaultErrorCallStackSkip + baseCallStackSkip
) {
try {
const stacklines = data.stack.split('\n').slice(skipIdx);
if (!stacklines.length) {
// There's no stack in this stack
// Should we try a previous index if skipIdx was set?
return null;
}
const lineMatch = stackReg.exec(stacklines[0]);
/* istanbul ignore else: failsafe */
if (lineMatch && lineMatch.length === 5) {
// extract class, function and alias names
let className = '';
let functionName = '';
let functionAlias = '';
if (lineMatch[1] && lineMatch[1] !== '') {
// WARN: this will unset alias if alias is not present.
[functionName, functionAlias] = lineMatch[1]
.replace(/[[\]]/g, '')
.split(' as ');
functionAlias = functionAlias || '';
if (functionName.includes('.'))
[className, functionName] = functionName.split('.');
}
return {
fileName: lineMatch[2],
lineNumber: parseInt(lineMatch[3], 10),
columnNumber: parseInt(lineMatch[4], 10),
callStack: stacklines.join('\n'),
className,
functionName,
functionAlias,
callerName: lineMatch[1] || '',
};
// eslint-disable-next-line no-else-return
} else {
// will never get here unless nodejs has changes to Error
console.error('log4js.logger - defaultParseCallStack error'); // eslint-disable-line no-console
}
} catch (err) {
// will never get error unless nodejs has breaking changes to Error
console.error('log4js.logger - defaultParseCallStack error', err); // eslint-disable-line no-console
}
return null;
}
/**
* Logger to log messages.
* use {@see log4js#getLogger(String)} to get an instance.
*
* @name Logger
* @namespace Log4js
* @param name name of category to log to
* @param level - the loglevel for the category
* @param dispatch - the function which will receive the logevents
*
* @author Stephan Strittmatter
*/
class Logger {
constructor(name) {
if (!name) {
throw new Error('No category provided.');
}
this.category = name;
this.context = {};
/** @private */
this.callStackSkipIndex = 0;
/** @private */
this.parseCallStack = defaultParseCallStack;
debug(`Logger created (${this.category}, ${this.level})`);
}
get level() {
return levels.getLevel(
categories.getLevelForCategory(this.category),
levels.OFF
);
}
set level(level) {
categories.setLevelForCategory(
this.category,
levels.getLevel(level, this.level)
);
}
get useCallStack() {
return categories.getEnableCallStackForCategory(this.category);
}
set useCallStack(bool) {
categories.setEnableCallStackForCategory(this.category, bool === true);
}
get callStackLinesToSkip() {
return this.callStackSkipIndex;
}
set callStackLinesToSkip(number) {
if (typeof number !== 'number') {
throw new TypeError('Must be a number');
}
if (number < 0) {
throw new RangeError('Must be >= 0');
}
this.callStackSkipIndex = number;
}
log(level, ...args) {
const logLevel = levels.getLevel(level);
if (!logLevel) {
if (configuration.validIdentifier(level) && args.length > 0) {
// logLevel not found but of valid signature, WARN before fallback to INFO
this.log(
levels.WARN,
'log4js:logger.log: valid log-level not found as first parameter given:',
level
);
this.log(levels.INFO, `[${level}]`, ...args);
} else {
// apart from fallback, allow .log(...args) to be synonym with .log("INFO", ...args)
this.log(levels.INFO, level, ...args);
}
} else if (this.isLevelEnabled(logLevel)) {
this._log(logLevel, args);
}
}
isLevelEnabled(otherLevel) {
return this.level.isLessThanOrEqualTo(otherLevel);
}
_log(level, data) {
debug(`sending log data (${level}) to appenders`);
const error = data.find((item) => item instanceof Error);
let callStack;
if (this.useCallStack) {
try {
if (error) {
callStack = this.parseCallStack(
error,
this.callStackSkipIndex + baseCallStackSkip
);
}
} catch (_err) {
// Ignore Error and use the original method of creating a new Error.
}
callStack =
callStack ||
this.parseCallStack(
new Error(),
this.callStackSkipIndex +
defaultErrorCallStackSkip +
baseCallStackSkip
);
}
const loggingEvent = new LoggingEvent(
this.category,
level,
data,
this.context,
callStack,
error
);
clustering.send(loggingEvent);
}
addContext(key, value) {
this.context[key] = value;
}
removeContext(key) {
delete this.context[key];
}
clearContext() {
this.context = {};
}
setParseCallStackFunction(parseFunction) {
if (typeof parseFunction === 'function') {
this.parseCallStack = parseFunction;
} else if (typeof parseFunction === 'undefined') {
this.parseCallStack = defaultParseCallStack;
} else {
throw new TypeError('Invalid type passed to setParseCallStackFunction');
}
}
}
function addLevelMethods(target) {
const level = levels.getLevel(target);
const levelStrLower = level.toString().toLowerCase();
const levelMethod = levelStrLower.replace(/_([a-z])/g, (g) =>
g[1].toUpperCase()
);
const isLevelMethod = levelMethod[0].toUpperCase() + levelMethod.slice(1);
Logger.prototype[`is${isLevelMethod}Enabled`] = function () {
return this.isLevelEnabled(level);
};
Logger.prototype[levelMethod] = function (...args) {
this.log(level, ...args);
};
}
levels.levels.forEach(addLevelMethods);
configuration.addListener(() => {
levels.levels.forEach(addLevelMethods);
});
module.exports = Logger;

110
my-app/node_modules/log4js/package.json generated vendored Executable file
View file

@ -0,0 +1,110 @@
{
"name": "log4js",
"version": "6.9.1",
"description": "Port of Log4js to work with node.",
"homepage": "https://log4js-node.github.io/log4js-node/",
"files": [
"lib",
"types/*.d.ts",
"CHANGELOG.md",
"SECURITY.md"
],
"keywords": [
"logging",
"log",
"log4j",
"node"
],
"license": "Apache-2.0",
"main": "./lib/log4js",
"types": "./types/log4js.d.ts",
"contributors": [
"Gareth Jones <gareth.nomiddlename@gmail.com>",
"Lam Wei Li <lam_wei_li@hotmail.com>"
],
"repository": {
"type": "git",
"url": "https://github.com/log4js-node/log4js-node.git"
},
"bugs": {
"url": "http://github.com/log4js-node/log4js-node/issues"
},
"engines": {
"node": ">=8.0"
},
"scripts": {
"prepare": "is-ci || husky install",
"pretest": "npm run prettier --if-present && eslint \"lib/**/*.js\" \"test/**/*.js\"",
"prettier": "prettier --check \"**/*.*\"",
"prettier:fix": "prettier --write \"**/*.*\"",
"test": "tap \"test/tap/**/*.js\" --cov --reporter=classic --coverage-report=text --coverage-report=html --timeout=45",
"typings": "tsc -p types/tsconfig.json"
},
"directories": {
"test": "test",
"lib": "lib"
},
"dependencies": {
"date-format": "^4.0.14",
"debug": "^4.3.4",
"flatted": "^3.2.7",
"rfdc": "^1.3.0",
"streamroller": "^3.1.5"
},
"devDependencies": {
"@commitlint/cli": "^17.4.4",
"@commitlint/config-conventional": "^17.4.4",
"@log4js-node/sandboxed-module": "^2.2.1",
"callsites": "^3.1.0",
"deep-freeze": "0.0.1",
"eslint": "^8.34.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-prettier": "^8.6.0",
"eslint-import-resolver-node": "^0.3.7",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-prettier": "^4.2.1",
"fs-extra": "^11.1.0",
"husky": "^8.0.3",
"is-ci": "^3.0.1",
"nyc": "^15.1.0",
"prettier": "^2.8.4",
"proxyquire": "^2.1.3",
"tap": "^16.3.4",
"typescript": "^4.9.5"
},
"browser": {
"os": false,
"streamroller": false,
"./lib/clustering.js": "./lib/clusteringBrowser.js",
"./lib/appenders/dateFile.js": "./lib/appenders/ignoreBrowser.js",
"./lib/appenders/file.js": "./lib/appenders/ignoreBrowser.js",
"./lib/appenders/fileSync.js": "./lib/appenders/ignoreBrowser.js",
"./lib/appenders/multiFile.js": "./lib/appenders/ignoreBrowser.js"
},
"prettier": {
"trailingComma": "es5",
"arrowParens": "always",
"overrides": [
{
"files": [
"*.cjs"
],
"options": {
"parser": "typescript"
}
}
]
},
"tap": {
"check-coverage": true
},
"nyc": {
"all": true,
"include": [
"lib/**/*.js"
],
"require": [
"./test/sandbox-coverage"
]
}
}

484
my-app/node_modules/log4js/types/log4js.d.ts generated vendored Executable file
View file

@ -0,0 +1,484 @@
// Type definitions for log4js
type Format =
| string
| ((req: any, res: any, formatter: (str: string) => string) => string);
export interface Log4js {
getLogger(category?: string): Logger;
configure(filename: string): Log4js;
configure(config: Configuration): Log4js;
isConfigured(): boolean;
addLayout(
name: string,
config: (a: any) => (logEvent: LoggingEvent) => string
): void;
connectLogger(
logger: Logger,
options: { format?: Format; level?: string; nolog?: any }
): any; // express.Handler;
levels: Levels;
shutdown(cb?: (error?: Error) => void): void;
}
export function getLogger(category?: string): Logger;
export function configure(filename: string): Log4js;
export function configure(config: Configuration): Log4js;
export function isConfigured(): boolean;
export function addLayout(
name: string,
config: (a: any) => (logEvent: LoggingEvent) => any
): void;
export function connectLogger(
logger: Logger,
options: {
format?: Format;
level?: string;
nolog?: any;
statusRules?: any[];
context?: boolean;
}
): any; // express.Handler;
export function recording(): Recording;
export const levels: Levels;
export function shutdown(cb?: (error?: Error) => void): void;
export interface BasicLayout {
type: 'basic';
}
export interface ColoredLayout {
type: 'colored' | 'coloured';
}
export interface MessagePassThroughLayout {
type: 'messagePassThrough';
}
export interface DummyLayout {
type: 'dummy';
}
export interface Level {
isEqualTo(other: string): boolean;
isEqualTo(otherLevel: Level): boolean;
isLessThanOrEqualTo(other: string): boolean;
isLessThanOrEqualTo(otherLevel: Level): boolean;
isGreaterThanOrEqualTo(other: string): boolean;
isGreaterThanOrEqualTo(otherLevel: Level): boolean;
colour: string;
level: number;
levelStr: string;
}
/**
* A parsed CallStack from an `Error.stack` trace
*/
export interface CallStack {
functionName: string;
fileName: string;
lineNumber: number;
columnNumber: number;
/**
* The stack string after the skipped lines
*/
callStack: string;
}
export interface LoggingEvent extends Partial<CallStack> {
categoryName: string; // name of category
level: Level; // level of message
data: any[]; // objects to log
startTime: Date;
pid: number;
context: any;
cluster?: {
workerId: number;
worker: number;
};
/**
* The first Error object in the data if there is one
*/
error?: Error;
serialise(): string;
}
export type Token = ((logEvent: LoggingEvent) => string) | string;
export interface PatternLayout {
type: 'pattern';
// specifier for the output format, using placeholders as described below
pattern: string;
// user-defined tokens to be used in the pattern
tokens?: { [name: string]: Token };
}
export interface CustomLayout {
[key: string]: any;
type: string;
}
export type Layout =
| BasicLayout
| ColoredLayout
| MessagePassThroughLayout
| DummyLayout
| PatternLayout
| CustomLayout;
/**
* Category Filter
*
* @see https://log4js-node.github.io/log4js-node/categoryFilter.html
*/
export interface CategoryFilterAppender {
type: 'categoryFilter';
// the category (or categories if you provide an array of values) that will be excluded from the appender.
exclude?: string | string[];
// the name of the appender to filter. see https://log4js-node.github.io/log4js-node/layouts.html
appender?: string;
}
/**
* No Log Filter
*
* @see https://log4js-node.github.io/log4js-node/noLogFilter.html
*/
export interface NoLogFilterAppender {
type: 'noLogFilter';
// the regular expression (or the regular expressions if you provide an array of values)
// will be used for evaluating the events to pass to the appender.
// The events, which will match the regular expression, will be excluded and so not logged.
exclude: string | string[];
// the name of an appender, defined in the same configuration, that you want to filter.
appender: string;
}
/**
* Console Appender
*
* @see https://log4js-node.github.io/log4js-node/console.html
*/
export interface ConsoleAppender {
type: 'console';
// (defaults to ColoredLayout)
layout?: Layout;
}
export interface FileAppender {
type: 'file';
// the path of the file where you want your logs written.
filename: string;
// (defaults to undefined) the maximum size (in bytes) for the log file. If not specified or 0, then no log rolling will happen.
maxLogSize?: number | string;
// (defaults to 5) the number of old log files to keep (excluding the hot file).
backups?: number;
// (defaults to BasicLayout)
layout?: Layout;
// (defaults to utf-8)
encoding?: string;
// (defaults to 0o600)
mode?: number;
// (defaults to a)
flags?: string;
// (defaults to false) compress the backup files using gzip (backup files will have .gz extension)
compress?: boolean;
// (defaults to false) preserve the file extension when rotating log files (`file.log` becomes `file.1.log` instead of `file.log.1`).
keepFileExt?: boolean;
// (defaults to .) the filename separator when rolling. e.g.: abc.log`.`1 or abc`.`1.log (keepFileExt)
fileNameSep?: string;
}
export interface SyncfileAppender {
type: 'fileSync';
// the path of the file where you want your logs written.
filename: string;
// (defaults to undefined) the maximum size (in bytes) for the log file. If not specified or 0, then no log rolling will happen.
maxLogSize?: number | string;
// (defaults to 5) the number of old log files to keep (excluding the hot file).
backups?: number;
// (defaults to BasicLayout)
layout?: Layout;
// (defaults to utf-8)
encoding?: string;
// (defaults to 0o600)
mode?: number;
// (defaults to a)
flags?: string;
}
export interface DateFileAppender {
type: 'dateFile';
// the path of the file where you want your logs written.
filename: string;
// (defaults to yyyy-MM-dd) the pattern to use to determine when to roll the logs.
/**
* The following strings are recognised in the pattern:
* - yyyy : the full year, use yy for just the last two digits
* - MM : the month
* - dd : the day of the month
* - hh : the hour of the day (24-hour clock)
* - mm : the minute of the hour
* - ss : seconds
* - SSS : milliseconds (although I'm not sure you'd want to roll your logs every millisecond)
* - O : timezone (capital letter o)
*/
pattern?: string;
// (defaults to BasicLayout)
layout?: Layout;
// (defaults to utf-8)
encoding?: string;
// (defaults to 0o600)
mode?: number;
// (defaults to a)
flags?: string;
// (defaults to false) compress the backup files using gzip (backup files will have .gz extension)
compress?: boolean;
// (defaults to false) preserve the file extension when rotating log files (`file.log` becomes `file.2017-05-30.log` instead of `file.log.2017-05-30`).
keepFileExt?: boolean;
// (defaults to .) the filename separator when rolling. e.g.: abc.log`.`2013-08-30 or abc`.`2013-08-30.log (keepFileExt)
fileNameSep?: string;
// (defaults to false) include the pattern in the name of the current log file.
alwaysIncludePattern?: boolean;
// (defaults to 1) the number of old files that matches the pattern to keep (excluding the hot file).
numBackups?: number;
}
export interface LogLevelFilterAppender {
type: 'logLevelFilter';
// the name of an appender, defined in the same configuration, that you want to filter
appender: string;
// the minimum level of event to allow through the filter
level: string;
// (defaults to FATAL) the maximum level of event to allow through the filter
maxLevel?: string;
}
export interface MultiFileAppender {
type: 'multiFile';
// the base part of the generated log filename
base: string;
// the value to use to split files (see below).
property: string;
// the suffix for the generated log filename.
extension: string;
}
export interface MultiprocessAppender {
type: 'multiprocess';
// controls whether the appender listens for log events sent over the network, or is responsible for serialising events and sending them to a server.
mode: 'master' | 'worker';
// (only needed if mode == master) the name of the appender to send the log events to
appender?: string;
// (defaults to 5000) the port to listen on, or send to
loggerPort?: number;
// (defaults to localhost) the host/IP address to listen on, or send to
loggerHost?: string;
}
export interface RecordingAppender {
type: 'recording';
}
export interface StandardErrorAppender {
type: 'stderr';
// (defaults to ColoredLayout)
layout?: Layout;
}
export interface StandardOutputAppender {
type: 'stdout';
// (defaults to ColoredLayout)
layout?: Layout;
}
/**
* TCP Appender
*
* @see https://log4js-node.github.io/log4js-node/tcp.html
*/
export interface TCPAppender {
type: 'tcp';
// (defaults to 5000)
port?: number;
// (defaults to localhost)
host?: string;
// (defaults to __LOG4JS__)
endMsg?: string;
// (defaults to a serialized log event)
layout?: Layout;
}
export interface CustomAppender {
type: string | AppenderModule;
[key: string]: any;
}
/**
* Mapping of all Appenders to allow for declaration merging
* @example
* declare module 'log4js' {
* interface Appenders {
* StorageTestAppender: {
* type: 'storageTest';
* storageMedium: 'dvd' | 'usb' | 'hdd';
* };
* }
* }
*/
export interface Appenders {
CategoryFilterAppender: CategoryFilterAppender;
ConsoleAppender: ConsoleAppender;
FileAppender: FileAppender;
SyncfileAppender: SyncfileAppender;
DateFileAppender: DateFileAppender;
LogLevelFilterAppender: LogLevelFilterAppender;
NoLogFilterAppender: NoLogFilterAppender;
MultiFileAppender: MultiFileAppender;
MultiprocessAppender: MultiprocessAppender;
RecordingAppender: RecordingAppender;
StandardErrorAppender: StandardErrorAppender;
StandardOutputAppender: StandardOutputAppender;
TCPAppender: TCPAppender;
CustomAppender: CustomAppender;
}
export interface AppenderModule {
configure: (
config?: Config,
layouts?: LayoutsParam,
findAppender?: () => AppenderFunction,
levels?: Levels
) => AppenderFunction;
}
export type AppenderFunction = (loggingEvent: LoggingEvent) => void;
// TODO: Actually add types here...
// It's supposed to be the full config element
export type Config = any;
export interface LayoutsParam {
basicLayout: LayoutFunction;
messagePassThroughLayout: LayoutFunction;
patternLayout: LayoutFunction;
colouredLayout: LayoutFunction;
coloredLayout: LayoutFunction;
dummyLayout: LayoutFunction;
addLayout: (name: string, serializerGenerator: LayoutFunction) => void;
layout: (name: string, config: PatternToken) => LayoutFunction;
}
export interface PatternToken {
pattern: string; // TODO type this to enforce good pattern...
tokens: { [tokenName: string]: () => any };
}
export type LayoutFunction = (loggingEvent: LoggingEvent) => string;
export type Appender = Appenders[keyof Appenders];
export interface Levels {
ALL: Level;
MARK: Level;
TRACE: Level;
DEBUG: Level;
INFO: Level;
WARN: Level;
ERROR: Level;
FATAL: Level;
OFF: Level;
levels: Level[];
getLevel(level: Level | string, defaultLevel?: Level): Level;
addLevels(customLevels: object): void;
}
export interface Configuration {
appenders: { [name: string]: Appender };
categories: {
[name: string]: {
appenders: string[];
level: string;
enableCallStack?: boolean;
};
};
pm2?: boolean;
pm2InstanceVar?: string;
levels?:
| Levels
| {
[name: string]: {
value: number;
colour: string;
};
};
disableClustering?: boolean;
}
export interface Recording {
configure(): AppenderFunction;
replay(): LoggingEvent[];
playback(): LoggingEvent[];
reset(): void;
erase(): void;
}
export interface Logger {
new (name: string): Logger;
readonly category: string;
level: Level | string;
log(level: Level | string, ...args: any[]): void;
isLevelEnabled(level?: string): boolean;
isTraceEnabled(): boolean;
isDebugEnabled(): boolean;
isInfoEnabled(): boolean;
isWarnEnabled(): boolean;
isErrorEnabled(): boolean;
isFatalEnabled(): boolean;
_log(level: Level, data: any): void;
addContext(key: string, value: any): void;
removeContext(key: string): void;
clearContext(): void;
/**
* Replace the basic parse function with a new custom one
* - Note that linesToSkip will be based on the origin of the Error object in addition to the callStackLinesToSkip (at least 1)
* @param parseFunction the new parseFunction. Use `undefined` to reset to the base implementation
*/
setParseCallStackFunction(
parseFunction: (error: Error, linesToSkip: number) => CallStack | undefined
): void;
/**
* Adjust the value of linesToSkip when the parseFunction is called.
*
* Cannot be less than 0.
*/
callStackLinesToSkip: number;
trace(message: any, ...args: any[]): void;
debug(message: any, ...args: any[]): void;
info(message: any, ...args: any[]): void;
warn(message: any, ...args: any[]): void;
error(message: any, ...args: any[]): void;
fatal(message: any, ...args: any[]): void;
mark(message: any, ...args: any[]): void;
}