diff options
| -rw-r--r-- | .env.sample | 4 | ||||
| -rw-r--r-- | package-lock.json | 290 | ||||
| -rw-r--r-- | package.json | 4 | ||||
| -rw-r--r-- | src/index.ts | 90 | ||||
| -rw-r--r-- | src/util/config.ts | 38 | ||||
| -rw-r--r-- | src/util/logger.ts | 21 |
6 files changed, 390 insertions, 57 deletions
diff --git a/.env.sample b/.env.sample index b3fdc29..05eed7a 100644 --- a/.env.sample +++ b/.env.sample @@ -1,6 +1,8 @@ PORT=3000 +BIND_ADDRESS=localhost TOKEN= HOST_DIR=/dist UPLOAD_LIMIT=4194304 MONGO_URI=mongodb://localhost:27017 -MONGO_DB=ao-coverage
\ No newline at end of file +MONGO_DB=ao-coverage +LOG_LEVEL=info
\ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 84cbad6..75dbf3f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -154,6 +154,14 @@ "uri-js": "4.2.2" } }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "1.9.3" + } + }, "array-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", @@ -177,6 +185,14 @@ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" }, + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "requires": { + "lodash": "4.17.15" + } + }, "async-limiter": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", @@ -247,6 +263,66 @@ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "3.2.1", + "escape-string-regexp": "1.0.5", + "supports-color": "5.5.0" + } + }, + "color": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/color/-/color-3.0.0.tgz", + "integrity": "sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w==", + "requires": { + "color-convert": "1.9.3", + "color-string": "1.5.3" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "color-string": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", + "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", + "requires": { + "color-name": "1.1.3", + "simple-swizzle": "0.2.2" + } + }, + "colornames": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/colornames/-/colornames-1.1.1.tgz", + "integrity": "sha1-+IiQMGhcfE/54qVZ9Qd+t2qBb5Y=" + }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" + }, + "colorspace": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.2.tgz", + "integrity": "sha512-vt+OoIP2d76xLhjwbBaucYlNSpPsrJWPlBTtwCpQKIu6/CSMutyzX93O/Do0qzpH3YoHEes8YEFXyZ797rEhzQ==", + "requires": { + "color": "3.0.0", + "text-hex": "1.0.0" + } + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -349,6 +425,16 @@ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, + "diagnostics": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/diagnostics/-/diagnostics-1.1.1.tgz", + "integrity": "sha512-8wn1PmdunLJ9Tqbx+Fx/ZEuHfJf4NKSN2ZBj7SJC/OWRWha843+WsTjqMe1B5E3p28jqBlp+mJ2fPVxPyNgYKQ==", + "requires": { + "colorspace": "1.1.2", + "enabled": "1.0.2", + "kuler": "1.0.1" + } + }, "domexception": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", @@ -376,16 +462,34 @@ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, + "enabled": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/enabled/-/enabled-1.0.2.tgz", + "integrity": "sha1-ll9lE9LC0cX0ZStkouM5ZGf8L5M=", + "requires": { + "env-variable": "0.0.5" + } + }, "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" }, + "env-variable": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/env-variable/-/env-variable-0.0.5.tgz", + "integrity": "sha512-zoB603vQReOFvTg5xMl9I1P2PnHsHQQKTEowsKKD7nseUfJq6UWzK+4YtlWUO1nhiQUxe6XMkk+JleSZD1NZFA==" + }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, "escodegen": { "version": "1.12.0", "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.12.0.tgz", @@ -455,6 +559,15 @@ "vary": "1.1.2" } }, + "express-winston": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/express-winston/-/express-winston-4.0.1.tgz", + "integrity": "sha512-HQZ/d2UPuZIr/PNiLOHX+CF2Q9srfBy1GDK7yIJ+MvX6MU49ggM25XynSNmC5RRPlD2ju3Zic+mCTQtixP1gzQ==", + "requires": { + "chalk": "2.4.2", + "lodash": "4.17.15" + } + }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -480,6 +593,16 @@ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" }, + "fast-safe-stringify": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", + "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==" + }, + "fecha": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-2.3.3.tgz", + "integrity": "sha512-lUGBnIamTAwk4znq5BcqsDaxSmZ9nDVJaij6NvRt/Tg4R69gERA+otPKbS86ROw9nxVMw2/mp1fnaiWqbs6Sdg==" + }, "finalhandler": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", @@ -541,6 +664,11 @@ "har-schema": "2.0.0" } }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, "html-encoding-sniffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", @@ -594,11 +722,26 @@ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==" }, + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", @@ -668,6 +811,14 @@ "verror": "1.10.0" } }, + "kuler": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/kuler/-/kuler-1.0.1.tgz", + "integrity": "sha512-J9nVUucG1p/skKul6DU3PUZrhs0LPulNaeUOox0IyXDi8S4CztTHs1gQphhuZmzXG7VOQSf6NJfKuzteQLv9gQ==", + "requires": { + "colornames": "1.1.1" + } + }, "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", @@ -687,6 +838,25 @@ "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" }, + "logform": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.1.2.tgz", + "integrity": "sha512-+lZh4OpERDBLqjiwDLpAWNQu6KMjnlXH2ByZwCuSqVPJletw0kTWJf5CgSNAUKn1KUkv3m2cUz/LK8zyEy7wzQ==", + "requires": { + "colors": "1.4.0", + "fast-safe-stringify": "2.0.7", + "fecha": "2.3.3", + "ms": "2.1.2", + "triple-beam": "1.3.0" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -765,6 +935,11 @@ "ee-first": "1.1.1" } }, + "one-time": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/one-time/-/one-time-0.0.4.tgz", + "integrity": "sha1-+M33eISCb+Tf+T46nMN7HkSAdC4=" + }, "optionator": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", @@ -814,6 +989,11 @@ "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", "dev": true }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, "proxy-addr": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", @@ -854,6 +1034,16 @@ "unpipe": "1.0.0" } }, + "readable-stream": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", + "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", + "requires": { + "inherits": "2.0.3", + "string_decoder": "1.3.0", + "util-deprecate": "1.0.2" + } + }, "request": { "version": "2.88.0", "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", @@ -1020,6 +1210,14 @@ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "requires": { + "is-arrayish": "0.3.2" + } + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -1051,6 +1249,11 @@ "tweetnacl": "0.14.5" } }, + "stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" + }, "statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", @@ -1061,11 +1264,39 @@ "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "5.2.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" + } + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "3.0.0" + } + }, "symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" }, + "text-hex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", + "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" + }, "toidentifier": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", @@ -1089,6 +1320,11 @@ "punycode": "2.1.1" } }, + "triple-beam": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", + "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" + }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -1137,6 +1373,11 @@ "punycode": "2.1.1" } }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -1208,6 +1449,55 @@ "webidl-conversions": "4.0.2" } }, + "winston": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.2.1.tgz", + "integrity": "sha512-zU6vgnS9dAWCEKg/QYigd6cgMVVNwyTzKs81XZtTFuRwJOcDdBg7AU0mXVyNbs7O5RH2zdv+BdNZUlx7mXPuOw==", + "requires": { + "async": "2.6.3", + "diagnostics": "1.1.1", + "is-stream": "1.1.0", + "logform": "2.1.2", + "one-time": "0.0.4", + "readable-stream": "3.4.0", + "stack-trace": "0.0.10", + "triple-beam": "1.3.0", + "winston-transport": "4.3.0" + } + }, + "winston-transport": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.3.0.tgz", + "integrity": "sha512-B2wPuwUi3vhzn/51Uukcao4dIduEiPOcOt9HJ3QeaXgkJ5Z7UwpBzxS4ZGNHtrxrUvTwemsQiSys0ihOf8Mp1A==", + "requires": { + "readable-stream": "2.3.6", + "triple-beam": "1.3.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.1", + "safe-buffer": "5.1.2", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "5.1.2" + } + } + } + }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", diff --git a/package.json b/package.json index 818b361..44e13a2 100644 --- a/package.json +++ b/package.json @@ -20,9 +20,11 @@ "badgen": "3.0.1", "dotenv": "8.2.0", "express": "4.17.1", + "express-winston": "^4.0.1", "jsdom": "^15.2.1", "mongodb": "^3.3.5", - "typescript": "^3.7.2" + "typescript": "^3.7.2", + "winston": "^3.2.1" }, "devDependencies": { "prettier": "^1.19.1" diff --git a/src/index.ts b/src/index.ts index 4955ba6..53592da 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,50 +6,56 @@ import { MongoClient } from "mongodb"; import path from "path"; import fs from "fs"; +import winston from "winston"; +import expressWinston from "express-winston"; + +dotenv.config(); + import formats, { Format } from "./formats"; import Metadata from "./metadata"; +import logger_config from "./util/logger"; +import { config_or_error, handle_shutdown } from "./util/config"; // Start-up configuration -dotenv.config(); +const BIND_ADDRESS = process.env.BIND_ADDRESS || "localhost"; const PORT = Number(process.env.PORT || 3000); const TOKEN = process.env.TOKEN || ""; const UPLOAD_LIMIT = Number(process.env.UPLOAD_LIMIT || 4194304); -const MONGO_URI = - process.env.MONGO_URI || - (() => { - throw Error("MONGO_URI must be defined"); - })(); + +const logger = winston.createLogger(logger_config("ROOT")); + +const MONGO_URI = config_or_error("MONGO_URI"); const MONGO_DB = process.env.MONGO_DB || "ao-coverage"; -const HOST_DIR = - process.env.HOST_DIR || - (() => { - throw Error("HOST_DIR must be defined"); - })(); +const HOST_DIR = config_or_error("HOST_DIR"); fs.accessSync(HOST_DIR, fs.constants.R_OK | fs.constants.W_OK); if (!path.isAbsolute(HOST_DIR)) { - throw Error("HOST_DIR must be an absolute path"); + logger.error("HOST_DIR must be an absolute path"); + process.exit(1); } new MongoClient(MONGO_URI, { useUnifiedTopology: true }).connect( (err, mongo) => { if (err !== null) { - throw err; + logger.error(err); + process.exit(1); } const app: express.Application = express(); const metadata = new Metadata(mongo.db(MONGO_DB)); + app.use( + expressWinston.logger({ + ...logger_config("HTTP"), + // filter out token query param from URL + msg: + '{{req.method}} {{req.url.replace(/token=[-\\w.~]*(&*)/, "token=$1")}} - {{res.statusCode}} {{res.responseTime}}ms' + }) + ); + // Upload HTML file app.post("/v1/:org/:repo/:branch/:commit.html", (req, res) => { const { org, repo, branch, commit } = req.params; - console.info( - "POST request to /v1/%s/%s/%s/%s.html", - org, - repo, - branch, - commit - ); const { token, format } = req.query; //TODO @Metadata token should come from metadata @@ -112,11 +118,10 @@ new MongoClient(MONGO_URI, { useUnifiedTopology: true }).connect( app.get("/v1/:org/:repo/:branch.svg", (req, res) => { const { org, repo, branch } = req.params; - console.info("GET request to /v1/%s/%s/%s.svg", org, repo, branch); metadata.getHeadCommit(org, repo, branch).then( commit => { - console.debug( + logger.debug( "Found commit %s for ORB %s/%s/%s", commit, org, @@ -136,11 +141,10 @@ new MongoClient(MONGO_URI, { useUnifiedTopology: true }).connect( app.get("/v1/:org/:repo/:branch.html", (req, res) => { const { org, repo, branch } = req.params; - console.info("GET request to /v1/%s/%s/%s.html", org, repo, branch); metadata.getHeadCommit(org, repo, branch).then( commit => { - console.debug( + logger.debug( "Found commit %s for ORB %s/%s/%s", commit, org, @@ -161,13 +165,6 @@ new MongoClient(MONGO_URI, { useUnifiedTopology: true }).connect( // provide hard link for commit app.get("/v1/:org/:repo/:branch/:commit.svg", (req, res) => { const { org, repo, branch, commit } = req.params; - console.info( - "GET request to /v1/%s/%s/%s/%s.svg", - org, - repo, - branch, - commit - ); res.sendFile(path.join(HOST_DIR, org, repo, branch, commit, "badge.svg")); }); @@ -175,39 +172,22 @@ new MongoClient(MONGO_URI, { useUnifiedTopology: true }).connect( // provide hard link for commit app.get("/v1/:org/:repo/:branch/:commit.html", (req, res) => { const { org, repo, branch, commit } = req.params; - console.info( - "GET request to /v1/%s/%s/%s/%s.html", - org, - repo, - branch, - commit - ); res.sendFile( path.join(HOST_DIR, org, repo, branch, commit, "index.html") ); }); - const server = app.listen(PORT, () => { - console.log("Express started on port " + PORT); + app.use(expressWinston.errorLogger(logger_config("_ERR"))); + + const server = app.listen(PORT, BIND_ADDRESS, () => { + logger.info("Express has started: http://%s:%d/", BIND_ADDRESS, PORT); }); // application exit handling - const handle_closure = (signal: NodeJS.Signals) => { - console.log("%s signal received. Closing shop.", signal); - - mongo.close().then(() => { - console.log("Mongo client connection closed."); - server.close(() => { - console.log("Express down."); - process.exit(); - }); - }); - }; - const handle_codes: NodeJS.Signals[] = ["SIGTERM", "SIGHUP", "SIGINT"]; - const process_event = (code: NodeJS.Signals) => - process.on(code, handle_closure); - handle_codes.map(process_event); + handle_codes.map((code: NodeJS.Signals) => { + process.on(code, handle_shutdown(mongo, server)); + }); } ); diff --git a/src/util/config.ts b/src/util/config.ts new file mode 100644 index 0000000..c155e64 --- /dev/null +++ b/src/util/config.ts @@ -0,0 +1,38 @@ +import winston from "winston"; +import { MongoClient } from "mongodb"; +import { Server } from "http"; + +import logger_config from "./logger"; + +const logger = winston.createLogger(logger_config("ROOT")); + +export const config_or_error = (var_name: string) => { + if (!process.env[var_name]) { + logger.error("%s must be defined", var_name); + process.exit(1); + return ""; + } else { + return process.env[var_name] || ""; + } +}; + +export const handle_shutdown = (mongo: MongoClient, server: Server) => ( + signal: NodeJS.Signals +) => { + logger.warn("%s signal received. Closing shop.", signal); + + mongo + .close() + .then(() => { + logger.info("MongoDB client connection closed."); + return new Promise((res, rej) => + server.close(err => { + logger.info("Express down."); + (err ? rej : res)(err); + }) + ); + }) + .finally(() => { + process.exit(0); + }); +}; diff --git a/src/util/logger.ts b/src/util/logger.ts new file mode 100644 index 0000000..bafb829 --- /dev/null +++ b/src/util/logger.ts @@ -0,0 +1,21 @@ +import winston from "winston"; +const { combine, splat, timestamp, label, colorize, printf } = winston.format; +const { Console } = winston.transports; + +const LOG_LEVEL = process.env.LOG_LEVEL || "info"; + +/** + * Provides standard logging format and output for the server. + */ +export default (clazz: string, level: string = LOG_LEVEL) => ({ + format: combine( + splat(), + timestamp(), + label({ label: clazz }), + colorize(), + printf(({ level, message, label, timestamp }) => { + return `${timestamp} [${label}] ${level}: ${message}`; + }) + ), + transports: [new Console({ level: level })] +}); |
