Doceditor: add logger and custom server

This commit is contained in:
Timofey Boyko 2024-02-27 19:04:57 +03:00
parent 6748387c8e
commit 2afdf69688
7 changed files with 265 additions and 9 deletions

View File

@ -0,0 +1,7 @@
{
"PORT": "5013",
"HOSTNAME": "localhost",
"app": {
"appsettings": "../../../buildtools/config"
}
}

View File

@ -0,0 +1,7 @@
{
"PORT": "5013",
"HOSTNAME": "localhost",
"app": {
"appsettings": "../../../../buildtools/config"
}
}

View File

@ -0,0 +1,35 @@
const nconf = require("nconf");
const path = require("path");
const confFile =
typeof process.env.NODE_ENV !== "undefined"
? "config.json"
: "config.deploy.json";
nconf.argv().env().file("config", path.join(__dirname, confFile));
getAndSaveAppsettings();
function getAndSaveAppsettings() {
let appsettings = nconf.get("app").appsettings;
if (!path.isAbsolute(appsettings)) {
appsettings = path.join(__dirname, appsettings);
}
const env = nconf.get("app").environment;
console.log("environment: " + env);
nconf.file(
"appsettingsWithEnv",
path.join(appsettings, "appsettings." + env + ".json"),
);
nconf.file("appsettings", path.join(appsettings, "appsettings.json"));
nconf.file(
"appsettingsServices",
path.join(appsettings, "appsettings.services.json"),
);
}
module.exports = nconf;

View File

@ -0,0 +1,104 @@
const winston = require("winston");
const WinstonCloudWatch = require("winston-cloudwatch");
const date = require("date-and-time");
const os = require("os");
const { randomUUID } = require("crypto");
require("winston-daily-rotate-file");
const path = require("path");
const fs = require("fs");
const config = require("../config/index.js");
let logPath = config.get("logPath");
let logLevel = config.get("logLevel") || "debug";
if (logPath != null) {
if (!path.isAbsolute(logPath)) {
logPath = path.join(__dirname, "..", logPath);
}
}
const fileName = logPath
? path.join(logPath, "editor.%DATE%.log")
: path.join(__dirname, "..", "..", "..", "Logs", "editor.%DATE%.log");
const dirName = path.dirname(fileName);
const aws = config.get("aws").cloudWatch;
const accessKeyId = aws.accessKeyId;
const secretAccessKey = aws.secretAccessKey;
const awsRegion = aws.region;
const logGroupName = aws.logGroupName;
const logStreamName = aws.logStreamName
.replace("${hostname}", os.hostname())
.replace("${applicationContext}", "Editor")
.replace("${guid}", randomUUID())
.replace("${date}", date.format(new Date(), "YYYY/MM/DDTHH.mm.ss"));
if (!fs.existsSync(dirName)) {
fs.mkdirSync(dirName);
}
const options = {
file: {
filename: fileName,
level: logLevel,
datePattern: "MM-DD",
handleExceptions: true,
humanReadableUnhandledException: true,
zippedArchive: true,
maxSize: "50m",
maxFiles: "30d",
json: true,
},
console: {
level: logLevel,
handleExceptions: true,
json: false,
colorize: true,
},
cloudWatch: {
name: "aws",
level: logLevel,
logStreamName: logStreamName,
logGroupName: logGroupName,
awsRegion: awsRegion,
jsonMessage: true,
awsOptions: {
credentials: {
accessKeyId: accessKeyId,
secretAccessKey: secretAccessKey,
},
},
},
};
let transports = [
new winston.transports.Console(options.console),
new winston.transports.DailyRotateFile(options.file),
];
if (aws != null && aws.accessKeyId !== "") {
transports.push(new WinstonCloudWatch(options.cloudWatch));
}
const customFormat = winston.format((info) => {
const now = new Date();
info.date = date.format(now, "YYYY-MM-DD HH:mm:ss");
info.applicationContext = "Editor";
info.level = info.level.toUpperCase();
const hostname = os.hostname();
info["instance-id"] = hostname;
return info;
})();
const ws = new winston.createLogger({
format: winston.format.combine(customFormat, winston.format.json()),
transports: transports,
exitOnError: false,
});
module.exports = ws;

View File

@ -4,19 +4,27 @@
"private": true,
"scripts": {
"build": "node ./scripts/buildTranslations.js && next build",
"start": "node ./scripts/buildTranslations.js && next dev -p 5013",
"start-prod": "next start -p 5013",
"lint": "next lint"
"start": "node ./scripts/buildTranslations.js && NODE_ENV=development node server.js",
"start-prod": "NODE_ENV=production node server.js",
"lint": "next lint",
"clean": "shx rm -rf .next",
"deploy": "shx --silent mkdir -p ../../../publish/web/editor && shx cp -r .next/* ../../../publish/web/editor && shx cp -f server.js ../../../publish/web/editor/server.js && shx cp -r lib/* ../../../publish/web/editor && shx cp -r config/* ../../../publish/web/editor"
},
"dependencies": {
"@aws-sdk/client-cloudwatch-logs": "^3.521.0",
"@onlyoffice/document-editor-react": "^1.4.1",
"date-and-time": "^3.1.1",
"i18next": "^20.6.1",
"mobx": "^6.8.0",
"morgan": "^1.10.0",
"next": "14.0.4",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-i18next": "^14.0.1",
"styled-components": "^5.3.9"
"styled-components": "^5.3.9",
"winston": "^3.11.0",
"winston-cloudwatch": "^6.2.0",
"winston-daily-rotate-file": "^5.0.0"
},
"devDependencies": {
"@svgr/webpack": "^8.1.0",
@ -26,6 +34,7 @@
"eslint": "^8",
"eslint-config-next": "14.0.4",
"prettier": "^3.2.4",
"shx": "^0.3.4",
"typescript": "^5"
}
}

View File

@ -0,0 +1,59 @@
const logger = require("morgan");
const { createServer } = require("http");
const { parse } = require("url");
const next = require("next");
const winston = require("./lib/logger");
const config = require("./config/index.js");
const dev = process.env.NODE_ENV === "development";
const port = config.get("PORT") ?? 5013;
const hostname = config.get("HOSTNAME") ?? "localhost";
// when using middleware `hostname` and `port` must be provided below
const app = next({ dev, hostname, port });
const handle = app.getRequestHandler();
winston.stream = {
write: (message) => winston.info(message),
};
// app.use(
// logger("dev", {
// stream: winston.stream,
// skip: function (req, res) {
// if (req.url == "/health") {
// return true;
// } else {
// return false;
// }
// },
// }),
// );
app.prepare().then(() => {
createServer(async (req, res) => {
try {
// Be sure to pass `true` as the second argument to `url.parse`.
// This tells it to parse the query portion of the URL.
const parsedUrl = parse(req.url, true);
// app.get("/health", (req, res) => {
// res.send({ status: "Healthy" });
// });
await handle(req, res, parsedUrl);
} catch (err) {
winston.error("Error occurred handling", req.url, err);
res.statusCode = 500;
res.end("internal server error");
}
})
.once("error", (err) => {
winston.error(err);
process.exit(1);
})
.listen(port, () => {
winston.info(`Server is listening on port ${port}`);
});
});

View File

@ -117,7 +117,7 @@ __metadata:
languageName: node
linkType: hard
"@aws-sdk/client-cloudwatch-logs@npm:^3.297.0":
"@aws-sdk/client-cloudwatch-logs@npm:^3.297.0, @aws-sdk/client-cloudwatch-logs@npm:^3.521.0":
version: 3.521.0
resolution: "@aws-sdk/client-cloudwatch-logs@npm:3.521.0"
dependencies:
@ -3034,22 +3034,29 @@ __metadata:
version: 0.0.0-use.local
resolution: "@docspace/doceditor@workspace:packages/doceditor"
dependencies:
"@aws-sdk/client-cloudwatch-logs": "npm:^3.521.0"
"@onlyoffice/document-editor-react": "npm:^1.4.1"
"@svgr/webpack": "npm:^8.1.0"
"@types/node": "npm:^20"
"@types/react": "npm:^18"
"@types/react-dom": "npm:^18"
date-and-time: "npm:^3.1.1"
eslint: "npm:^8"
eslint-config-next: "npm:14.0.4"
i18next: "npm:^20.6.1"
mobx: "npm:^6.8.0"
morgan: "npm:^1.10.0"
next: "npm:14.0.4"
prettier: "npm:^3.2.4"
react: "npm:^18.2.0"
react-dom: "npm:^18.2.0"
react-i18next: "npm:^14.0.1"
shx: "npm:^0.3.4"
styled-components: "npm:^5.3.9"
typescript: "npm:^5"
winston: "npm:^3.11.0"
winston-cloudwatch: "npm:^6.2.0"
winston-daily-rotate-file: "npm:^5.0.0"
languageName: unknown
linkType: soft
@ -13111,6 +13118,13 @@ __metadata:
languageName: node
linkType: hard
"date-and-time@npm:^3.1.1":
version: 3.1.1
resolution: "date-and-time@npm:3.1.1"
checksum: 149c5264e7f8622086c44fab7b29ffae7b2623e22140b97215354844cc31e8aefb773bbac3a4d59b8ea6459f1e428174bafced877ad714733b2479b31001b68e
languageName: node
linkType: hard
"dateformat@npm:^4.5.1":
version: 4.6.3
resolution: "dateformat@npm:4.6.3"
@ -22499,6 +22513,13 @@ __metadata:
languageName: node
linkType: hard
"object-hash@npm:^3.0.0":
version: 3.0.0
resolution: "object-hash@npm:3.0.0"
checksum: f498d456a20512ba7be500cef4cf7b3c183cc72c65372a549c9a0e6dd78ce26f375e9b1315c07592d3fde8f10d5019986eba35970570d477ed9a2a702514432a
languageName: node
linkType: hard
"object-inspect@npm:^1.13.1, object-inspect@npm:^1.7.0":
version: 1.13.1
resolution: "object-inspect@npm:1.13.1"
@ -27930,7 +27951,7 @@ __metadata:
languageName: node
linkType: hard
"triple-beam@npm:^1.3.0":
"triple-beam@npm:^1.3.0, triple-beam@npm:^1.4.1":
version: 1.4.1
resolution: "triple-beam@npm:1.4.1"
checksum: 2e881a3e8e076b6f2b85b9ec9dd4a900d3f5016e6d21183ed98e78f9abcc0149e7d54d79a3f432b23afde46b0885bdcdcbff789f39bc75de796316961ec07f61
@ -29650,7 +29671,7 @@ __metadata:
languageName: node
linkType: hard
"winston-cloudwatch@npm:^6.1.1":
"winston-cloudwatch@npm:^6.1.1, winston-cloudwatch@npm:^6.2.0":
version: 6.2.0
resolution: "winston-cloudwatch@npm:6.2.0"
dependencies:
@ -29682,7 +29703,21 @@ __metadata:
languageName: node
linkType: hard
"winston-transport@npm:^4.4.0, winston-transport@npm:^4.5.0":
"winston-daily-rotate-file@npm:^5.0.0":
version: 5.0.0
resolution: "winston-daily-rotate-file@npm:5.0.0"
dependencies:
file-stream-rotator: "npm:^0.6.1"
object-hash: "npm:^3.0.0"
triple-beam: "npm:^1.4.1"
winston-transport: "npm:^4.7.0"
peerDependencies:
winston: ^3
checksum: 4204deaea0f2a6a9d89747b734547e44d3c30681d6f871d6e146e64ce5807656a6d6fc51057e9c2bda792139356aa36ddd842ce458270e5a77cbd3ed002b7123
languageName: node
linkType: hard
"winston-transport@npm:^4.4.0, winston-transport@npm:^4.5.0, winston-transport@npm:^4.7.0":
version: 4.7.0
resolution: "winston-transport@npm:4.7.0"
dependencies:
@ -29693,7 +29728,7 @@ __metadata:
languageName: node
linkType: hard
"winston@npm:*, winston@npm:^3.8.2":
"winston@npm:*, winston@npm:^3.11.0, winston@npm:^3.8.2":
version: 3.11.0
resolution: "winston@npm:3.11.0"
dependencies: