From 2116a8b70aa171fb5b05bd16a048c0742c8821a6 Mon Sep 17 00:00:00 2001 From: Yuri Lysov Date: Sun, 5 Dec 2021 03:06:54 +0300 Subject: [PATCH 1/5] wip --- package-lock.json | 54 ++++++++++++++++++++++++++++++ package.json | 2 ++ src/module-3/controllers/groups.ts | 12 ++++++- src/module-3/index.ts | 34 ++++++++++++++++++- src/module-3/services/groups.ts | 7 ++-- 5 files changed, 105 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 59150ae..d5bbebb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1533,6 +1533,15 @@ "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", "dev": true }, + "@types/morgan": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@types/morgan/-/morgan-1.9.3.tgz", + "integrity": "sha512-BiLcfVqGBZCyNCnCH3F4o2GmDLrpy0HeBVnNlyZG4fo88ZiE9SoiBe3C+2ezuwbjlEyT+PDZ17//TAlRxAn75Q==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/node": { "version": "16.10.1", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.10.1.tgz", @@ -1907,6 +1916,14 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "requires": { + "safe-buffer": "5.1.2" + } + }, "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -3720,6 +3737,38 @@ "moment": ">= 2.9.0" } }, + "morgan": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", + "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", + "requires": { + "basic-auth": "~2.0.1", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-finished": "~2.3.0", + "on-headers": "~1.0.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -3847,6 +3896,11 @@ "ee-first": "1.1.1" } }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", diff --git a/package.json b/package.json index b4660f5..4f5f103 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "express": "^4.17.1", "express-joi-validation": "^5.0.0", "joi": "^17.4.2", + "morgan": "^1.10.0", "pg": "^8.7.1", "pg-hstore": "^2.3.4", "sequelize": "^6.9.0", @@ -32,6 +33,7 @@ "@babel/preset-env": "^7.15.6", "@babel/preset-typescript": "^7.15.0", "@types/express": "^4.17.13", + "@types/morgan": "^1.9.3", "@typescript-eslint/eslint-plugin": "^5.1.0", "@typescript-eslint/parser": "^5.1.0", "babel-eslint": "^10.1.0", diff --git a/src/module-3/controllers/groups.ts b/src/module-3/controllers/groups.ts index 29ce3e8..998df90 100644 --- a/src/module-3/controllers/groups.ts +++ b/src/module-3/controllers/groups.ts @@ -1,4 +1,4 @@ -import express from "express"; +import express, { NextFunction, Request, Response } from "express"; import { createValidator } from "express-joi-validation"; import * as GroupsService from "../services/groups"; import { Errors, GroupModel } from "../types"; @@ -8,6 +8,16 @@ import groupValidationSchema from "./validation/groups"; const validator = createValidator(); const router = express.Router(); +const middleware = (req: Request, res: Response, next: NextFunction) => { + // console.log(req.trailers, res); + // res.on("finish", () => { + // res. + // }) + console.log("stack", req.route.stack); + next(); + // args.next(); + // next(); +}; /* Get all groups */ router.get("/", async (req, res) => { diff --git a/src/module-3/index.ts b/src/module-3/index.ts index c79e912..11e65a7 100644 --- a/src/module-3/index.ts +++ b/src/module-3/index.ts @@ -1,4 +1,6 @@ -import express from "express"; +import express, { NextFunction, Request, Response } from "express"; +import morgan from "morgan"; +import { EventEmitter } from "stream"; import groupsRouter from "./controllers/groups"; import userGroupsRouter from "./controllers/user-groups"; import usersRouter from "./controllers/users"; @@ -6,6 +8,35 @@ import db from "./data-access"; const app = express(); +const cache = []; +export const emitter = new EventEmitter(); +emitter.addListener("addFn", (args: string) => { + cache.push(args); +}); + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +// const logFuncion = (fnName: string, args: any[]) => { +// return `function name: ${fnName}, args: ${args.toString()}`; +// }; + +const middleware = (req: Request, res: Response, next: NextFunction) => { + res.once("finish", () => { + console.log(cache); + }); + next(); +}; + +morgan.token("something", (req, res, rand) => { + // console.log({ chunk }); + // }); + // console.log(req.method); + return req.headers.tk; +}); + +app.use(morgan("INFO: :something")); + +// app.use(middleware); + app.listen(3000, () => db .authenticate() @@ -16,6 +47,7 @@ app.listen(3000, () => ) .then(() => app.use(express.json())) .then(() => { + app.use(middleware); app.use("/api/groups", groupsRouter); app.use("/api/users", usersRouter); app.use("/api/user-groups", userGroupsRouter); diff --git a/src/module-3/services/groups.ts b/src/module-3/services/groups.ts index 5dd1bdf..aabccfb 100644 --- a/src/module-3/services/groups.ts +++ b/src/module-3/services/groups.ts @@ -1,4 +1,5 @@ import { Model } from "sequelize/types"; +import { emitter } from ".."; import sequelize from "../data-access"; import Group from "../models/group"; import { Errors, GroupModel } from "../types"; @@ -12,10 +13,12 @@ export const find = async (id: string) => } }); -export const findAll = async () => - Group.findAll({ +export const findAll = async () => { + emitter.emit("addFn", `${findAll.name}`); + return Group.findAll({ raw: true }); +}; export const create = async (model: GroupModel) => { const { name } = model; From 785338bd1f69bef8611d853ee72daa16ec822848 Mon Sep 17 00:00:00 2001 From: Yuri Lysov Date: Sun, 5 Dec 2021 14:02:09 +0300 Subject: [PATCH 2/5] wip-2 --- package-lock.json | 292 ++++++++++++++++++++++++++++- package.json | 5 +- src/module-3/controllers/groups.ts | 3 + src/module-3/index.ts | 35 +--- src/module-3/logger.ts | 35 ++++ src/module-3/services/groups.ts | 3 +- 6 files changed, 341 insertions(+), 32 deletions(-) create mode 100644 src/module-3/logger.ts diff --git a/package-lock.json b/package-lock.json index d5bbebb..4d08cfe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1303,6 +1303,16 @@ "to-fast-properties": "^2.0.0" } }, + "@dabh/diagnostics": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.2.tgz", + "integrity": "sha512-+A1YivoVDNNVCdfozHSR8v/jyuuLTMXwjWuxPFlFlUapXoGc+Gj9mDlTDDfrwl7rXCl2tNZ0kE8sIBO6YOn96Q==", + "requires": { + "colorspace": "1.1.x", + "enabled": "2.0.x", + "kuler": "^2.0.0" + } + }, "@eslint/eslintrc": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.3.tgz", @@ -1481,6 +1491,15 @@ "@types/node": "*" } }, + "@types/bunyan": { + "version": "1.8.8", + "resolved": "https://registry.npmjs.org/@types/bunyan/-/bunyan-1.8.8.tgz", + "integrity": "sha512-Cblq+Yydg3u+sGiz2mjHjC5MPmdjY+No4qvHrF+BUhblsmSfMvsHLbOG62tPbonsqBj6sbWv1LHcsoe5Jw+/Ow==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/connect": { "version": "3.4.35", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", @@ -1842,6 +1861,11 @@ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true }, + "async": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.2.tgz", + "integrity": "sha512-H0E+qZaDEfx/FY4t7iLRv1W2fFI6+pyCeTw1uN20AQPiwqwM6ojPxHxdLv4z8hi2DtnW9BOckSspLucW7pIE5g==" + }, "babel-eslint": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", @@ -2030,6 +2054,17 @@ "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" }, + "bunyan": { + "version": "1.8.15", + "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.15.tgz", + "integrity": "sha512-0tECWShh6wUysgucJcBAoYegf3JJoZWibxdqhTm7OHPeT42qdjkZ29QCMcKwbgU1kiH+auSIasNRXMLWXafXig==", + "requires": { + "dtrace-provider": "~0.8", + "moment": "^2.19.3", + "mv": "~2", + "safe-json-stringify": "~1" + } + }, "bytes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", @@ -2170,6 +2205,30 @@ "mimic-response": "^1.0.0" } }, + "color": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "requires": { + "color-convert": "^1.9.3", + "color-string": "^1.6.0" + }, + "dependencies": { + "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-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -2182,8 +2241,30 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "color-string": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.0.tgz", + "integrity": "sha512-9Mrz2AQLefkH1UvASKj6v6hj/7eWgjnT/cVsR8CumieLoT+g900exWeNogqtweI8dxloXN9BDQTYro1oWu/5CQ==", + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" + }, + "colorspace": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", + "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", + "requires": { + "color": "^3.1.3", + "text-hex": "1.0.x" + } }, "commander": { "version": "2.20.3", @@ -2279,6 +2360,11 @@ } } }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -2403,6 +2489,15 @@ "resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.2.tgz", "integrity": "sha512-fmrwR04lsniq/uSr8yikThDTrM7epXHBAAjH9TbeH3rEA8tdCO7mRzB9hdmdGyJCxF8KERo9CITcm3kGuoyMhg==" }, + "dtrace-provider": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.8.tgz", + "integrity": "sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg==", + "optional": true, + "requires": { + "nan": "^2.14.0" + } + }, "duplexer": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", @@ -2431,6 +2526,11 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "enabled": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", + "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" + }, "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -2865,6 +2965,11 @@ "reusify": "^1.0.4" } }, + "fecha": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.1.tgz", + "integrity": "sha512-MMMQ0ludy/nBs1/o0zVOiKTpG7qMbonKUzjJgQFEuvq6INZ1OraKPRAWkBq5vlKLOUMpmNYG1JoN3oDPUQ9m3Q==" + }, "file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -2960,6 +3065,11 @@ "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", "dev": true }, + "fn.name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", + "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" + }, "forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -3281,6 +3391,11 @@ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" }, + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, "is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", @@ -3436,6 +3551,11 @@ "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", "dev": true }, + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==" + }, "is-string": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", @@ -3480,6 +3600,11 @@ "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", "dev": true }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -3566,6 +3691,11 @@ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true }, + "kuler": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", + "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" + }, "latest-version": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", @@ -3612,6 +3742,18 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "logform": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.3.0.tgz", + "integrity": "sha512-graeoWUH2knKbGthMtuG1EfaSPMZFZBIrhuJHhkS5ZseFBrc7DupCzihOQAzsK/qIKPQaPJ/lFQFctILUY5ARQ==", + "requires": { + "colors": "^1.2.1", + "fecha": "^4.2.0", + "ms": "^2.1.1", + "safe-stable-stringify": "^1.1.0", + "triple-beam": "^1.3.0" + } + }, "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", @@ -3772,8 +3914,48 @@ "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "mv": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", + "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", + "optional": true, + "requires": { + "mkdirp": "~0.5.1", + "ncp": "~2.0.0", + "rimraf": "~2.4.0" + }, + "dependencies": { + "glob": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", + "optional": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "rimraf": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", + "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", + "optional": true, + "requires": { + "glob": "^6.0.1" + } + } + } + }, + "nan": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", + "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", + "optional": true }, "nanocolors": { "version": "0.2.12", @@ -3787,6 +3969,12 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, + "ncp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", + "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", + "optional": true + }, "negotiator": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", @@ -3909,6 +4097,14 @@ "wrappy": "1" } }, + "one-time": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", + "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", + "requires": { + "fn.name": "1.x.x" + } + }, "optionator": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", @@ -4172,6 +4368,11 @@ "integrity": "sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==", "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==" + }, "progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", @@ -4436,6 +4637,17 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, + "safe-json-stringify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz", + "integrity": "sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg==", + "optional": true + }, + "safe-stable-stringify": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-1.1.1.tgz", + "integrity": "sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw==" + }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -4610,6 +4822,14 @@ "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==", "dev": true }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "requires": { + "is-arrayish": "^0.3.1" + } + }, "slash": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", @@ -4653,6 +4873,11 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, + "stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" + }, "statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", @@ -4744,6 +4969,11 @@ "has-flag": "^3.0.0" } }, + "text-hex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", + "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -4795,6 +5025,11 @@ "nopt": "~1.0.10" } }, + "triple-beam": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", + "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" + }, "tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", @@ -5106,6 +5341,55 @@ "string-width": "^4.0.0" } }, + "winston": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.3.3.tgz", + "integrity": "sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw==", + "requires": { + "@dabh/diagnostics": "^2.0.2", + "async": "^3.1.0", + "is-stream": "^2.0.0", + "logform": "^2.2.0", + "one-time": "^1.0.0", + "readable-stream": "^3.4.0", + "stack-trace": "0.0.x", + "triple-beam": "^1.3.0", + "winston-transport": "^4.4.0" + } + }, + "winston-transport": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.4.0.tgz", + "integrity": "sha512-Lc7/p3GtqtqPBYYtS6KCN3c77/2QCev51DvcJKbkFPQNoj1sinkGwLGFDxkXY9J6p9+EPnYs+D90uwbnaiURTw==", + "requires": { + "readable-stream": "^2.3.7", + "triple-beam": "^1.2.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "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.0" + } + } + } + }, "wkx": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/wkx/-/wkx-0.5.0.tgz", diff --git a/package.json b/package.json index 4f5f103..7c572a8 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "dependencies": { "@types/event-stream": "^3.3.34", "@types/node": "^16.10.1", + "bunyan": "^1.8.15", "csvtojson": "^2.0.10", "dotenv": "^10.0.0", "event-stream": "^4.0.1", @@ -24,7 +25,8 @@ "pg-hstore": "^2.3.4", "sequelize": "^6.9.0", "tslint": "^6.1.3", - "typescript": "^4.4.3" + "typescript": "^4.4.3", + "winston": "^3.3.3" }, "devDependencies": { "@babel/cli": "^7.15.7", @@ -32,6 +34,7 @@ "@babel/node": "^7.15.4", "@babel/preset-env": "^7.15.6", "@babel/preset-typescript": "^7.15.0", + "@types/bunyan": "^1.8.8", "@types/express": "^4.17.13", "@types/morgan": "^1.9.3", "@typescript-eslint/eslint-plugin": "^5.1.0", diff --git a/src/module-3/controllers/groups.ts b/src/module-3/controllers/groups.ts index 998df90..a83a47d 100644 --- a/src/module-3/controllers/groups.ts +++ b/src/module-3/controllers/groups.ts @@ -1,5 +1,6 @@ import express, { NextFunction, Request, Response } from "express"; import { createValidator } from "express-joi-validation"; +import { bunyanLogger } from "../logger"; import * as GroupsService from "../services/groups"; import { Errors, GroupModel } from "../types"; import { isNull } from "./utils"; @@ -18,11 +19,13 @@ const middleware = (req: Request, res: Response, next: NextFunction) => { // args.next(); // next(); }; + /* Get all groups */ router.get("/", async (req, res) => { try { const groups = await GroupsService.findAll(); + // groupsLogger.info("find groups"); res.status(200).send(groups); } catch (e) { res.status(500).send(e.message); diff --git a/src/module-3/index.ts b/src/module-3/index.ts index 11e65a7..19d05c5 100644 --- a/src/module-3/index.ts +++ b/src/module-3/index.ts @@ -1,41 +1,27 @@ -import express, { NextFunction, Request, Response } from "express"; +import express from "express"; import morgan from "morgan"; -import { EventEmitter } from "stream"; import groupsRouter from "./controllers/groups"; import userGroupsRouter from "./controllers/user-groups"; import usersRouter from "./controllers/users"; import db from "./data-access"; +import { LoggerStream } from "./logger"; const app = express(); -const cache = []; -export const emitter = new EventEmitter(); -emitter.addListener("addFn", (args: string) => { - cache.push(args); -}); - // eslint-disable-next-line @typescript-eslint/no-explicit-any // const logFuncion = (fnName: string, args: any[]) => { // return `function name: ${fnName}, args: ${args.toString()}`; // }; -const middleware = (req: Request, res: Response, next: NextFunction) => { - res.once("finish", () => { - console.log(cache); - }); - next(); -}; - -morgan.token("something", (req, res, rand) => { - // console.log({ chunk }); - // }); - // console.log(req.method); - return req.headers.tk; -}); - -app.use(morgan("INFO: :something")); +// morgan.token("something", (req, res, rand) => { +// // console.log({ chunk }); +// // }); +// // console.log(req.method); +// return req.headers.tk; +// }); -// app.use(middleware); +// app.use(morgan("INFO: :something")); +app.use(morgan("combined", { stream: new LoggerStream() })); app.listen(3000, () => db @@ -47,7 +33,6 @@ app.listen(3000, () => ) .then(() => app.use(express.json())) .then(() => { - app.use(middleware); app.use("/api/groups", groupsRouter); app.use("/api/users", usersRouter); app.use("/api/user-groups", userGroupsRouter); diff --git a/src/module-3/logger.ts b/src/module-3/logger.ts new file mode 100644 index 0000000..984a9bc --- /dev/null +++ b/src/module-3/logger.ts @@ -0,0 +1,35 @@ +import bunyan from "bunyan"; +import winston from "winston"; + +// const logger = winston.createLogger({ +// transports: [new winston.transports.Console()], +// exitOnError: false // do not exit on handled exceptions +// }); + +export const bunyanLogger = bunyan.createLogger({ + src: true, + name: "log", + streams: [ + { + level: "debug", + stream: process.stdout // log INFO and above to stdout + } + ] +}); + +// const groupsLogger = createLogger({ +// defaultMeta: { component: "groups" }, +// transports: [new transports.Console()] +// }); + +export class LoggerStream { + write(message: string) { + bunyanLogger.info(message); + } +} + +// module.exports = groupsLogger; + +// export const userLogger = createLogger({ +// transports: [new transports.Console()] +// }); diff --git a/src/module-3/services/groups.ts b/src/module-3/services/groups.ts index aabccfb..8405014 100644 --- a/src/module-3/services/groups.ts +++ b/src/module-3/services/groups.ts @@ -1,6 +1,6 @@ import { Model } from "sequelize/types"; -import { emitter } from ".."; import sequelize from "../data-access"; +import { bunyanLogger } from "../logger"; import Group from "../models/group"; import { Errors, GroupModel } from "../types"; import * as UserGroupsService from "./user-groups"; @@ -14,7 +14,6 @@ export const find = async (id: string) => }); export const findAll = async () => { - emitter.emit("addFn", `${findAll.name}`); return Group.findAll({ raw: true }); From 4998f02dcedf0c56b37aeb56a6c7f5589afacb5a Mon Sep 17 00:00:00 2001 From: Yuri Lysov Date: Sun, 5 Dec 2021 14:58:55 +0300 Subject: [PATCH 3/5] wip 3 --- src/module-3/controllers/groups.ts | 16 +++------------- src/module-3/index.ts | 9 +++++---- src/module-3/logger.ts | 12 +++++++++++- src/module-3/services/groups.ts | 2 +- 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/module-3/controllers/groups.ts b/src/module-3/controllers/groups.ts index a83a47d..51b4fdc 100644 --- a/src/module-3/controllers/groups.ts +++ b/src/module-3/controllers/groups.ts @@ -1,6 +1,6 @@ -import express, { NextFunction, Request, Response } from "express"; +import express from "express"; import { createValidator } from "express-joi-validation"; -import { bunyanLogger } from "../logger"; +import { logger } from ".."; import * as GroupsService from "../services/groups"; import { Errors, GroupModel } from "../types"; import { isNull } from "./utils"; @@ -9,22 +9,12 @@ import groupValidationSchema from "./validation/groups"; const validator = createValidator(); const router = express.Router(); -const middleware = (req: Request, res: Response, next: NextFunction) => { - // console.log(req.trailers, res); - // res.on("finish", () => { - // res. - // }) - console.log("stack", req.route.stack); - next(); - // args.next(); - // next(); -}; - /* Get all groups */ router.get("/", async (req, res) => { try { const groups = await GroupsService.findAll(); + logger.setFnData(GroupsService.findAll.name); // groupsLogger.info("find groups"); res.status(200).send(groups); } catch (e) { diff --git a/src/module-3/index.ts b/src/module-3/index.ts index 19d05c5..ada2479 100644 --- a/src/module-3/index.ts +++ b/src/module-3/index.ts @@ -1,13 +1,14 @@ import express from "express"; -import morgan from "morgan"; import groupsRouter from "./controllers/groups"; import userGroupsRouter from "./controllers/user-groups"; import usersRouter from "./controllers/users"; import db from "./data-access"; -import { LoggerStream } from "./logger"; +import { LoggerStore } from "./logger"; const app = express(); +export const logger = new LoggerStore(); + // eslint-disable-next-line @typescript-eslint/no-explicit-any // const logFuncion = (fnName: string, args: any[]) => { // return `function name: ${fnName}, args: ${args.toString()}`; @@ -20,8 +21,8 @@ const app = express(); // return req.headers.tk; // }); -// app.use(morgan("INFO: :something")); -app.use(morgan("combined", { stream: new LoggerStream() })); +// TODO: stay here +app.use(logger.getFnData); app.listen(3000, () => db diff --git a/src/module-3/logger.ts b/src/module-3/logger.ts index 984a9bc..42fe703 100644 --- a/src/module-3/logger.ts +++ b/src/module-3/logger.ts @@ -1,5 +1,4 @@ import bunyan from "bunyan"; -import winston from "winston"; // const logger = winston.createLogger({ // transports: [new winston.transports.Console()], @@ -21,6 +20,17 @@ export const bunyanLogger = bunyan.createLogger({ // defaultMeta: { component: "groups" }, // transports: [new transports.Console()] // }); +export class LoggerStore { + private fnData = null; + + getFnData() { + console.log(this.fnData); + } + + setFnData(val: string, args?: any) { + this.fnData = `fn: ${val}, args: ${args}`; + } +} export class LoggerStream { write(message: string) { diff --git a/src/module-3/services/groups.ts b/src/module-3/services/groups.ts index 8405014..744e6f7 100644 --- a/src/module-3/services/groups.ts +++ b/src/module-3/services/groups.ts @@ -1,6 +1,6 @@ import { Model } from "sequelize/types"; import sequelize from "../data-access"; -import { bunyanLogger } from "../logger"; +import { bunyanLogger, LoggerStore } from "../logger"; import Group from "../models/group"; import { Errors, GroupModel } from "../types"; import * as UserGroupsService from "./user-groups"; From ba071e3a173308cde9e938e53bafe33cba9b4545 Mon Sep 17 00:00:00 2001 From: Yuri Lysov Date: Tue, 7 Dec 2021 00:21:36 +0300 Subject: [PATCH 4/5] Add listening for different cases: function execution, errors exceptions, and so on regarding to the homework's requirements --- src/module-3/controllers/groups.ts | 145 +++++++++++++-------- src/module-3/controllers/user-groups.ts | 37 ++++-- src/module-3/controllers/users.ts | 159 ++++++++++++++++-------- src/module-3/index.ts | 24 ++-- src/module-3/logger.ts | 45 ------- src/module-3/loggers.ts | 76 +++++++++++ src/module-3/services/groups.ts | 1 - 7 files changed, 315 insertions(+), 172 deletions(-) delete mode 100644 src/module-3/logger.ts create mode 100644 src/module-3/loggers.ts diff --git a/src/module-3/controllers/groups.ts b/src/module-3/controllers/groups.ts index 51b4fdc..87abba1 100644 --- a/src/module-3/controllers/groups.ts +++ b/src/module-3/controllers/groups.ts @@ -1,6 +1,6 @@ import express from "express"; import { createValidator } from "express-joi-validation"; -import { logger } from ".."; +import { logger } from "../loggers"; import * as GroupsService from "../services/groups"; import { Errors, GroupModel } from "../types"; import { isNull } from "./utils"; @@ -11,75 +11,122 @@ const router = express.Router(); /* Get all groups */ -router.get("/", async (req, res) => { - try { - const groups = await GroupsService.findAll(); +router.get( + "/", + (req, res, next) => { logger.setFnData(GroupsService.findAll.name); - // groupsLogger.info("find groups"); - res.status(200).send(groups); - } catch (e) { - res.status(500).send(e.message); + next(); + }, + async (req, res) => { + try { + const groups = await GroupsService.findAll(); + res.status(200).send(groups); + } catch (e) { + logger.setError(e.message); + res.status(500).send(e.message); + } } -}); +); /* Find group by id */ -router.get("/:id", async (req, res) => { - try { - const id = req.params.id; - const group = await GroupsService.find(id); - if (group) { - return res.status(200).send(group); +router.get( + "/:id", + (req, res, next) => { + logger.setFnData(GroupsService.find.name, { id: req.params.id }); + next(); + }, + async (req, res) => { + try { + const id = req.params.id; + const group = await GroupsService.find(id); + if (group) { + return res.status(200).send(group); + } + const err = "Group not found"; + logger.setError(err); + res.status(404).send(err); + } catch (e) { + res.status(500).send(e.message); } - res.status(404).send("Group not found"); - } catch (e) { - res.status(500).send(e.message); } -}); +); /* Create new group */ -router.post("/", validator.body(groupValidationSchema), async (req, res) => { - try { - const body: GroupModel = req.body; - const isSuccess = await GroupsService.create(body); - if (!isSuccess) { - return res.status(400).send("Group with this name is already exists"); +router.post( + "/", + (req, res, next) => { + logger.setFnData(GroupsService.create.name, { body: req.body }); + next(); + }, + validator.body(groupValidationSchema), + async (req, res) => { + try { + const body: GroupModel = req.body; + const isSuccess = await GroupsService.create(body); + if (!isSuccess) { + const err = "Group with this name is already exists"; + logger.setError(err); + return res.status(400).send(err); + } + res.redirect("/api/groups"); + } catch (e) { + res.status(500).send(e.message); } - res.redirect("/api/groups"); - } catch (e) { - res.status(500).send(e.message); } -}); +); /* Delete group */ -router.delete("/:id", async (req, res) => { - try { - const id = req.params.id; - const isSuccess = await GroupsService.remove(id); - if (isNull(isSuccess)) { - return res.status(404).send("Something wrong"); +router.delete( + "/:id", + (req, res, next) => { + logger.setFnData(GroupsService.remove.name, { id: req.params.id }); + next(); + }, + async (req, res) => { + try { + const id = req.params.id; + const isSuccess = await GroupsService.remove(id); + if (isNull(isSuccess)) { + const err = "Something wrong"; + logger.setError(err); + return res.status(404).send(err); + } + res.redirect("/api/groups"); + } catch (e) { + res.status(500).send(e.message); } - res.redirect("/api/groups"); - } catch (e) { - res.status(500).send(e.message); } -}); +); /* Update group */ -router.put("/:id", validator.body(groupValidationSchema), async (req, res) => { - try { - const id = req.params.id; - const status = await GroupsService.update(id, req.body); - if ((status as Errors).type === "error") { - return res.status(404).send((status as Errors).message); +router.put( + "/:id", + [ + (req, res, next) => { + logger.setFnData(GroupsService.update.name, { + id: req.params.id, + body: req.body + }); + next(); + }, + validator.body(groupValidationSchema) + ], + async ({ params: { id }, body }, res) => { + try { + const status = await GroupsService.update(id, body); + if ((status as Errors).type === "error") { + logger.setError(status); + return res.status(404).send((status as Errors).message); + } + res.redirect("/api/groups"); + } catch (e) { + res.status(500).send(e.message); } - res.redirect("/api/groups"); - } catch (e) { - res.status(500).send(e.message); } -}); +); export default router; diff --git a/src/module-3/controllers/user-groups.ts b/src/module-3/controllers/user-groups.ts index e83b280..9d25916 100644 --- a/src/module-3/controllers/user-groups.ts +++ b/src/module-3/controllers/user-groups.ts @@ -1,5 +1,6 @@ import express from "express"; import { createValidator } from "express-joi-validation"; +import { logger } from "../loggers"; import { AddUsersToGroupModel } from "../services/types"; import * as UserGroupsService from "../services/user-groups"; import userGroupValidationSchema from "./validation/user-groups"; @@ -9,24 +10,40 @@ const router = express.Router(); /* Get user-groups list */ -router.get("/", async (req, res) => { - try { - const userGroups = await UserGroupsService.findAll(); - res.status(200).send(userGroups); - } catch (e) { - res.status(500).send(e.message); +router.get( + "/", + (req, res, next) => { + logger.setFnData(UserGroupsService.findAll.name); + next(); + }, + async (req, res) => { + try { + const userGroups = await UserGroupsService.findAll(); + res.status(200).send(userGroups); + } catch (e) { + res.status(500).send(e.message); + } } -}); +); /* Add user to any group by id*/ router.post( "/", - validator.body(userGroupValidationSchema), + [ + (req, res, next) => { + logger.setFnData(UserGroupsService.addUsersToGroup.name, { + groupId: req.body.groupId, + userIds: req.body.userIds + }); + next(); + }, + validator.body(userGroupValidationSchema) + ], async (req, res) => { try { - const body: AddUsersToGroupModel = req.body; - await UserGroupsService.addUsersToGroup(body.groupId, body.userIds); + const { groupId, userIds }: AddUsersToGroupModel = req.body; + await UserGroupsService.addUsersToGroup(groupId, userIds); res.redirect("/api/user-groups"); } catch (e) { res.status(500).send(e.message); diff --git a/src/module-3/controllers/users.ts b/src/module-3/controllers/users.ts index f9b8b9c..d0e0b50 100644 --- a/src/module-3/controllers/users.ts +++ b/src/module-3/controllers/users.ts @@ -1,5 +1,6 @@ -import express from "express"; +import express, { Request } from "express"; import { createValidator } from "express-joi-validation"; +import { logger } from "../loggers"; import * as UsersService from "../services/users"; import { UserModel } from "../types"; import { isNull } from "./utils"; @@ -10,76 +11,132 @@ const router = express.Router(); /* Get users list */ -router.get("/", async (req, res) => { - try { - const users = await UsersService.getAutoSuggestUsers( - req.body.loginSubstring, - req.body.limit - ); - res.status(200).send(users); - } catch (e) { - res.status(500).send(e.message); +router.get( + "/", + (req: Request, res, next) => { + logger.setFnData(UsersService.getAutoSuggestUsers.name, { + loginSubstring: req.body.loginSubstring, + limit: req.body.limit + }); + next(); + }, + async ({ body }, res) => { + try { + const users = await UsersService.getAutoSuggestUsers( + body.loginSubstring, + body.limit + ); + res.status(200).send(users); + } catch (e) { + logger.setError(e); + res.status(500).send(e.message); + } } -}); +); /* Find user by id */ -router.get("/:id", async (req, res) => { - try { - const id = req.params.id; - const user = await UsersService.find(id); - if (user) { - return res.status(200).send(user); +router.get( + "/:id", + (req, res, next) => { + logger.setFnData(UsersService.find.name, { id: req.params.id }); + next(); + }, + async (req, res) => { + try { + const id = req.params.id; + const user = await UsersService.find(id); + if (user) { + return res.status(200).send(user); + } + const err = "User not found"; + logger.setError(err); + res.status(404).send(err); + } catch (e) { + res.status(500).send(e.message); } - res.status(404).send("User not found"); - } catch (e) { - res.status(500).send(e.message); } -}); +); /* Create user */ -router.post("/", validator.body(userValidationSchema), async (req, res) => { - try { - const body: UserModel = req.body; - const isSuccess = await UsersService.create(body); - if (!isSuccess) { - return res.status(400).send("User with this login is already exists"); +router.post( + "/", + [ + (req: Request, res, next) => { + logger.setFnData(UsersService.create.name, { body: req.body }); + next(); + }, + validator.body(userValidationSchema) + ], + async (req, res) => { + try { + const body: UserModel = req.body; + const isSuccess = await UsersService.create(body); + if (!isSuccess) { + const err = "User with this login is already exists"; + logger.setError(err); + return res.status(400).send(err); + } + res.redirect("/api/users"); + } catch (e) { + res.status(500).send(e.message); } - res.redirect("/api/users"); - } catch (e) { - res.status(500).send(e.message); } -}); +); /* Delete user */ -router.delete("/:id", async (req, res) => { - try { - const id = req.params.id; - const isSuccess = await UsersService.remove(id); - if (isNull(isSuccess)) { - return res.status(404).send("User with this id is not found"); +router.delete( + "/:id", + (req: Request, res, next) => { + logger.setFnData(UsersService.remove.name, { id: req.params.id }); + next(); + }, + async (req, res) => { + try { + const id = req.params.id; + const isSuccess = await UsersService.remove(id); + if (isNull(isSuccess)) { + const err = "User with this id is not found"; + logger.setError(err); + return res.status(404).send(err); + } + res.redirect("/api/users"); + } catch (e) { + res.status(500).send(e.message); } - res.redirect("/api/users"); - } catch (e) { - res.status(500).send(e.message); } -}); +); /* Update user */ -router.put("/:id", validator.body(userValidationSchema), async (req, res) => { - try { - const id = req.params.id; - const isSuccess = await UsersService.update(id, req.body); - if (!isSuccess) { - return res.status(404).send("User with this id is not found"); +router.put( + "/:id", + [ + (req: Request, res, next) => { + logger.setFnData(UsersService.update.name, { + id: req.params.id, + body: req.body + }); + next(); + }, + validator.body(userValidationSchema) + ], + async (req, res) => { + try { + const id = req.params.id; + const isSuccess = await UsersService.update(id, req.body); + if (!isSuccess) { + const err = "User with this id is not found"; + logger.setError(err); + return res.status(404).send(err); + } + res.redirect("/api/users"); + } catch (e) { + res.status(500).send(e.message); } - res.redirect("/api/users"); - } catch (e) { - res.status(500).send(e.message); } -}); +); export default router; diff --git a/src/module-3/index.ts b/src/module-3/index.ts index ada2479..f769679 100644 --- a/src/module-3/index.ts +++ b/src/module-3/index.ts @@ -3,26 +3,17 @@ import groupsRouter from "./controllers/groups"; import userGroupsRouter from "./controllers/user-groups"; import usersRouter from "./controllers/users"; import db from "./data-access"; -import { LoggerStore } from "./logger"; +import { + errorLoggerMiddleware, + initHandlers, + mainLoggerMiddleware +} from "./loggers"; const app = express(); -export const logger = new LoggerStore(); +initHandlers(); -// eslint-disable-next-line @typescript-eslint/no-explicit-any -// const logFuncion = (fnName: string, args: any[]) => { -// return `function name: ${fnName}, args: ${args.toString()}`; -// }; - -// morgan.token("something", (req, res, rand) => { -// // console.log({ chunk }); -// // }); -// // console.log(req.method); -// return req.headers.tk; -// }); - -// TODO: stay here -app.use(logger.getFnData); +app.use(errorLoggerMiddleware); app.listen(3000, () => db @@ -34,6 +25,7 @@ app.listen(3000, () => ) .then(() => app.use(express.json())) .then(() => { + app.use(mainLoggerMiddleware); app.use("/api/groups", groupsRouter); app.use("/api/users", usersRouter); app.use("/api/user-groups", userGroupsRouter); diff --git a/src/module-3/logger.ts b/src/module-3/logger.ts deleted file mode 100644 index 42fe703..0000000 --- a/src/module-3/logger.ts +++ /dev/null @@ -1,45 +0,0 @@ -import bunyan from "bunyan"; - -// const logger = winston.createLogger({ -// transports: [new winston.transports.Console()], -// exitOnError: false // do not exit on handled exceptions -// }); - -export const bunyanLogger = bunyan.createLogger({ - src: true, - name: "log", - streams: [ - { - level: "debug", - stream: process.stdout // log INFO and above to stdout - } - ] -}); - -// const groupsLogger = createLogger({ -// defaultMeta: { component: "groups" }, -// transports: [new transports.Console()] -// }); -export class LoggerStore { - private fnData = null; - - getFnData() { - console.log(this.fnData); - } - - setFnData(val: string, args?: any) { - this.fnData = `fn: ${val}, args: ${args}`; - } -} - -export class LoggerStream { - write(message: string) { - bunyanLogger.info(message); - } -} - -// module.exports = groupsLogger; - -// export const userLogger = createLogger({ -// transports: [new transports.Console()] -// }); diff --git a/src/module-3/loggers.ts b/src/module-3/loggers.ts new file mode 100644 index 0000000..30194ae --- /dev/null +++ b/src/module-3/loggers.ts @@ -0,0 +1,76 @@ +import { NextFunction, Request, Response } from "express"; +import morgan from "morgan"; +import winston from "winston"; + +export let logger: LoggerStore = null; + +export class LoggerStore { + private fnName = null; + private fnArgs = null; + private error = null; + + getFnData() { + console.log({ + ...(this.fnName ? { fnName: this.fnName } : undefined), + ...(this.fnArgs ? { fnArgs: this.fnArgs } : undefined), + ...(this.error ? { error: this.error } : undefined) + }); + } + + setFnData(name: string, args?: any) { + this.fnName = name; + this.fnArgs = args; + } + + setError(message: any) { + this.error = message; + } +} + +const winstonLogger = winston.createLogger({ + transports: [ + new winston.transports.Console({ + level: "error", + handleExceptions: true + }) + ], + format: winston.format.combine( + winston.format.timestamp({ format: "YYYY-MM-DD HH:mm:ss:ms" }), + winston.format.colorize({ all: true }), + winston.format.printf( + (info) => `${info.timestamp} ${info.level}: ${info.message}` + ) + ), + exitOnError: false +}); + +export const errorLoggerMiddleware = morgan("tiny", { + stream: { + write: (message) => winstonLogger.error(message) + }, + skip: (req, res) => res.statusCode !== 500 +}); + +export const mainLoggerMiddleware = ( + req: Request, + res: Response, + next: NextFunction +) => { + req.once("close", () => { + logger.getFnData(); + }); + next(); +}; + +export const initHandlers = () => { + logger = new LoggerStore(); + + process.on("uncaughtException", (err) => { + console.log("We found an uncaught exception."); + console.log(err.stack); + }); + + process.on("unhandledRejection", (error) => { + console.log("unhandledRejection", error); + }); +}; diff --git a/src/module-3/services/groups.ts b/src/module-3/services/groups.ts index 744e6f7..a4ed5f5 100644 --- a/src/module-3/services/groups.ts +++ b/src/module-3/services/groups.ts @@ -1,6 +1,5 @@ import { Model } from "sequelize/types"; import sequelize from "../data-access"; -import { bunyanLogger, LoggerStore } from "../logger"; import Group from "../models/group"; import { Errors, GroupModel } from "../types"; import * as UserGroupsService from "./user-groups"; From 66a0f75fcf193e1a265300377a917117489b8ed6 Mon Sep 17 00:00:00 2001 From: Yuri Lysov Date: Sun, 19 Dec 2021 01:50:01 +0300 Subject: [PATCH 5/5] Upd loggers working (add single and universal logger function which allows to use itself simpler and in one line as routers middleware) --- src/module-3/controllers/groups.ts | 104 ++++++++---------------- src/module-3/controllers/user-groups.ts | 33 +++----- src/module-3/controllers/users.ts | 93 +++++++-------------- src/module-3/loggers.ts | 16 +++- 4 files changed, 89 insertions(+), 157 deletions(-) diff --git a/src/module-3/controllers/groups.ts b/src/module-3/controllers/groups.ts index 87abba1..a8e8ea9 100644 --- a/src/module-3/controllers/groups.ts +++ b/src/module-3/controllers/groups.ts @@ -1,6 +1,6 @@ import express from "express"; import { createValidator } from "express-joi-validation"; -import { logger } from "../loggers"; +import { log, logger } from "../loggers"; import * as GroupsService from "../services/groups"; import { Errors, GroupModel } from "../types"; import { isNull } from "./utils"; @@ -11,56 +11,38 @@ const router = express.Router(); /* Get all groups */ -router.get( - "/", - (req, res, next) => { - logger.setFnData(GroupsService.findAll.name); - next(); - }, - async (req, res) => { - try { - const groups = await GroupsService.findAll(); - res.status(200).send(groups); - } catch (e) { - logger.setError(e.message); - res.status(500).send(e.message); - } +router.get("/", log(GroupsService.findAll), async (req, res) => { + try { + const groups = await GroupsService.findAll(); + res.status(200).send(groups); + } catch (e) { + logger.setError(e.message); + res.status(500).send(e.message); } -); +}); /* Find group by id */ -router.get( - "/:id", - (req, res, next) => { - logger.setFnData(GroupsService.find.name, { id: req.params.id }); - next(); - }, - async (req, res) => { - try { - const id = req.params.id; - const group = await GroupsService.find(id); - if (group) { - return res.status(200).send(group); - } - const err = "Group not found"; - logger.setError(err); - res.status(404).send(err); - } catch (e) { - res.status(500).send(e.message); +router.get("/:id", log(GroupsService.find), async (req, res) => { + try { + const id = req.params.id; + const group = await GroupsService.find(id); + if (group) { + return res.status(200).send(group); } + const err = "Group not found"; + logger.setError(err); + res.status(404).send(err); + } catch (e) { + res.status(500).send(e.message); } -); +}); /* Create new group */ router.post( "/", - (req, res, next) => { - logger.setFnData(GroupsService.create.name, { body: req.body }); - next(); - }, - validator.body(groupValidationSchema), + [log(GroupsService.create), validator.body(groupValidationSchema)], async (req, res) => { try { const body: GroupModel = req.body; @@ -79,42 +61,26 @@ router.post( /* Delete group */ -router.delete( - "/:id", - (req, res, next) => { - logger.setFnData(GroupsService.remove.name, { id: req.params.id }); - next(); - }, - async (req, res) => { - try { - const id = req.params.id; - const isSuccess = await GroupsService.remove(id); - if (isNull(isSuccess)) { - const err = "Something wrong"; - logger.setError(err); - return res.status(404).send(err); - } - res.redirect("/api/groups"); - } catch (e) { - res.status(500).send(e.message); +router.delete("/:id", log(GroupsService.remove), async (req, res) => { + try { + const id = req.params.id; + const isSuccess = await GroupsService.remove(id); + if (isNull(isSuccess)) { + const err = "Something wrong"; + logger.setError(err); + return res.status(404).send(err); } + res.redirect("/api/groups"); + } catch (e) { + res.status(500).send(e.message); } -); +}); /* Update group */ router.put( "/:id", - [ - (req, res, next) => { - logger.setFnData(GroupsService.update.name, { - id: req.params.id, - body: req.body - }); - next(); - }, - validator.body(groupValidationSchema) - ], + [log(GroupsService.update), validator.body(groupValidationSchema)], async ({ params: { id }, body }, res) => { try { const status = await GroupsService.update(id, body); diff --git a/src/module-3/controllers/user-groups.ts b/src/module-3/controllers/user-groups.ts index 9d25916..67ca29b 100644 --- a/src/module-3/controllers/user-groups.ts +++ b/src/module-3/controllers/user-groups.ts @@ -1,6 +1,6 @@ import express from "express"; import { createValidator } from "express-joi-validation"; -import { logger } from "../loggers"; +import { log, logger } from "../loggers"; import { AddUsersToGroupModel } from "../services/types"; import * as UserGroupsService from "../services/user-groups"; import userGroupValidationSchema from "./validation/user-groups"; @@ -10,34 +10,22 @@ const router = express.Router(); /* Get user-groups list */ -router.get( - "/", - (req, res, next) => { - logger.setFnData(UserGroupsService.findAll.name); - next(); - }, - async (req, res) => { - try { - const userGroups = await UserGroupsService.findAll(); - res.status(200).send(userGroups); - } catch (e) { - res.status(500).send(e.message); - } +router.get("/", log(UserGroupsService.findAll), async (req, res) => { + try { + const userGroups = await UserGroupsService.findAll(); + res.status(200).send(userGroups); + } catch (e) { + logger.setError(e); + res.status(500).send(e.message); } -); +}); /* Add user to any group by id*/ router.post( "/", [ - (req, res, next) => { - logger.setFnData(UserGroupsService.addUsersToGroup.name, { - groupId: req.body.groupId, - userIds: req.body.userIds - }); - next(); - }, + log(UserGroupsService.addUsersToGroup), validator.body(userGroupValidationSchema) ], async (req, res) => { @@ -46,6 +34,7 @@ router.post( await UserGroupsService.addUsersToGroup(groupId, userIds); res.redirect("/api/user-groups"); } catch (e) { + logger.setError(e); res.status(500).send(e.message); } } diff --git a/src/module-3/controllers/users.ts b/src/module-3/controllers/users.ts index d0e0b50..459d94b 100644 --- a/src/module-3/controllers/users.ts +++ b/src/module-3/controllers/users.ts @@ -1,6 +1,6 @@ -import express, { Request } from "express"; +import express from "express"; import { createValidator } from "express-joi-validation"; -import { logger } from "../loggers"; +import { log, logger } from "../loggers"; import * as UsersService from "../services/users"; import { UserModel } from "../types"; import { isNull } from "./utils"; @@ -13,13 +13,7 @@ const router = express.Router(); router.get( "/", - (req: Request, res, next) => { - logger.setFnData(UsersService.getAutoSuggestUsers.name, { - loginSubstring: req.body.loginSubstring, - limit: req.body.limit - }); - next(); - }, + log(UsersService.getAutoSuggestUsers), async ({ body }, res) => { try { const users = await UsersService.getAutoSuggestUsers( @@ -36,39 +30,26 @@ router.get( /* Find user by id */ -router.get( - "/:id", - (req, res, next) => { - logger.setFnData(UsersService.find.name, { id: req.params.id }); - next(); - }, - async (req, res) => { - try { - const id = req.params.id; - const user = await UsersService.find(id); - if (user) { - return res.status(200).send(user); - } - const err = "User not found"; - logger.setError(err); - res.status(404).send(err); - } catch (e) { - res.status(500).send(e.message); +router.get("/:id", log(UsersService.find), async (req, res) => { + try { + const id = req.params.id; + const user = await UsersService.find(id); + if (user) { + return res.status(200).send(user); } + const err = "User not found"; + logger.setError(err); + res.status(404).send(err); + } catch (e) { + res.status(500).send(e.message); } -); +}); /* Create user */ router.post( "/", - [ - (req: Request, res, next) => { - logger.setFnData(UsersService.create.name, { body: req.body }); - next(); - }, - validator.body(userValidationSchema) - ], + [log(UsersService.create), validator.body(userValidationSchema)], async (req, res) => { try { const body: UserModel = req.body; @@ -87,42 +68,26 @@ router.post( /* Delete user */ -router.delete( - "/:id", - (req: Request, res, next) => { - logger.setFnData(UsersService.remove.name, { id: req.params.id }); - next(); - }, - async (req, res) => { - try { - const id = req.params.id; - const isSuccess = await UsersService.remove(id); - if (isNull(isSuccess)) { - const err = "User with this id is not found"; - logger.setError(err); - return res.status(404).send(err); - } - res.redirect("/api/users"); - } catch (e) { - res.status(500).send(e.message); +router.delete("/:id", log(UsersService.remove), async (req, res) => { + try { + const id = req.params.id; + const isSuccess = await UsersService.remove(id); + if (isNull(isSuccess)) { + const err = "User with this id is not found"; + logger.setError(err); + return res.status(404).send(err); } + res.redirect("/api/users"); + } catch (e) { + res.status(500).send(e.message); } -); +}); /* Update user */ router.put( "/:id", - [ - (req: Request, res, next) => { - logger.setFnData(UsersService.update.name, { - id: req.params.id, - body: req.body - }); - next(); - }, - validator.body(userValidationSchema) - ], + [log(UsersService.update), validator.body(userValidationSchema)], async (req, res) => { try { const id = req.params.id; diff --git a/src/module-3/loggers.ts b/src/module-3/loggers.ts index 30194ae..61d4b95 100644 --- a/src/module-3/loggers.ts +++ b/src/module-3/loggers.ts @@ -10,6 +10,10 @@ export class LoggerStore { private error = null; getFnData() { + console.log("\n"); + console.log("============================================"); + console.log("\n"); + console.log("Info of the executed function:"); console.log({ ...(this.fnName ? { fnName: this.fnName } : undefined), ...(this.fnArgs ? { fnArgs: this.fnArgs } : undefined), @@ -17,9 +21,9 @@ export class LoggerStore { }); } - setFnData(name: string, args?: any) { + setFnData(name: string, { body, params }: Request) { this.fnName = name; - this.fnArgs = args; + this.fnArgs = { ...body, ...params }; } setError(message: any) { @@ -74,3 +78,11 @@ export const initHandlers = () => { console.log("unhandledRejection", error); }); }; + +export const log = (fn: (...params: any) => void) => { + return (req: Request, res: Response, next: NextFunction) => { + logger.setError(null); + logger.setFnData(fn.name, req); + next(); + }; +};