Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature] Added server side logging #244

Merged
merged 3 commits into from
May 28, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Expand Up @@ -38,3 +38,6 @@ client/assets/*
!client/assets/fonts/
server/config.json
compilation-stats.json

#logs
logs/
16 changes: 16 additions & 0 deletions README.md
Expand Up @@ -325,6 +325,22 @@ login_form:

In order to enable users to log via third-party services like Google and Facebook, the ["Social Login" feature of OpenWISP Radius](https://openwisp-radius.readthedocs.io/en/latest/user/social_login.html) must be configured and enabled.

#### Configuring Logging

There are certain environment variables used to configure server logging. The details of environment variables to configure logging are mentioned below:

| Environment Variable | Detail |
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **LOG_LEVEL** | (optional) This can be used to set the level of logging. The available values are `warn` and `debug`. By default log level is set to `debug` during development and `warn` during production. |
codesankalp marked this conversation as resolved.
Show resolved Hide resolved
| **ALL_LOG_FILE** | (optional) To configure the path of the log file for all logs. The default path is `logs/all.log` |
| **ERROR_LOG_FILE** | (optional) To configure the path of the log file for error logs. The default path is `logs/error.log` |
| **WARN_LOG_FILE** | (optional) To configure the path of the log file for warn logs. The default path is `logs/warn.log` |
| **INFO_LOG_FILE** | (optional) To configure the path of the log file for info logs. The default path is `logs/info.log` |
| **HTTP_LOG_FILE** | (optional) To configure the path of the log file for http logs. The default path is `logs/http.log` |
| **DEBUG_LOG_FILE** | (optional) To configure the path of the log file for http logs. The default path is `logs/debug.log` |

All the **HTTP requests** get logged by default in the console during development.

### License

See [LICENSE](https://github.com/openwisp/openwisp-wifi-login-pages/blob/master/LICENSE).
5 changes: 4 additions & 1 deletion package.json
Expand Up @@ -5,6 +5,7 @@
"main": "src/index.js",
"dependencies": {
"@babel/register": "^7.10.1",
"@types/morgan": "^1.9.2",
"autoprefixer": "^9.8.0",
"axios": "^0.21.1",
"compression": "^1.7.4",
Expand All @@ -18,6 +19,7 @@
"js-yaml": "^3.14.0",
"jsdom": "^16.4.0",
"marked": "^2.0.0",
"morgan": "^1.10.0",
"nodemon": "^2.0.4",
"prop-types": "^15.7.2",
"qs": "^6.9.4",
Expand All @@ -33,7 +35,8 @@
"redux": "^4.0.5",
"redux-thunk": "^2.3.0",
"tsutils": "^3.17.1",
"universal-cookie-express": "^4.0.3"
"universal-cookie-express": "^4.0.3",
"winston": "^3.3.3"
},
"devDependencies": {
"@babel/cli": "^7.10.1",
Expand Down
7 changes: 3 additions & 4 deletions server/controllers/mobile-phone-number-change-controller.js
Expand Up @@ -5,7 +5,7 @@ import qs from "qs";

import config from "../config.json";
import defaultConfig from "../utils/default-config";
import logInternalError from "../utils/log-internal-error";
import Logger from "../utils/logger";

const mobilePhoneNumberChange = (req, res) => {
const reqOrg = req.params.organization;
Expand Down Expand Up @@ -39,16 +39,15 @@ const mobilePhoneNumberChange = (req, res) => {
.send(response.data);
})
.catch((error) => {
if (error.response && error.response.status === 500)
logInternalError(error);
Logger.error(error);
// forward error
try {
res
.status(error.response.status)
.type("application/json")
.send(error.response.data);
} catch (err) {
logInternalError(error);
Logger.error(error);
res.status(500).type("application/json").send({
response_code: "INTERNAL_SERVER_ERROR",
});
Expand Down
12 changes: 5 additions & 7 deletions server/controllers/mobile-phone-token-controller.js
Expand Up @@ -5,7 +5,7 @@ import qs from "qs";

import config from "../config.json";
import defaultConfig from "../utils/default-config";
import logInternalError from "../utils/log-internal-error";
import Logger from "../utils/logger";

export const createMobilePhoneToken = (req, res) => {
const reqOrg = req.params.organization;
Expand Down Expand Up @@ -39,16 +39,15 @@ export const createMobilePhoneToken = (req, res) => {
.send(response.data);
})
.catch((error) => {
if (error.response && error.response.status === 500)
logInternalError(error);
Logger.error(error);
// forward error
try {
res
.status(error.response.status)
.type("application/json")
.send(error.response.data);
} catch (err) {
logInternalError(error);
Logger.error(error);
res.status(500).type("application/json").send({
response_code: "INTERNAL_SERVER_ERROR",
});
Expand Down Expand Up @@ -98,16 +97,15 @@ export const verifyMobilePhoneToken = (req, res) => {
.send(response.data);
})
.catch((error) => {
if (error.response && error.response.status === 500)
logInternalError(error);
Logger.error(error);
// forward error
try {
res
.status(error.response.status)
.type("application/json")
.send(error.response.data);
} catch (err) {
logInternalError(error);
Logger.error(error);
res.status(500).type("application/json").send({
response_code: "INTERNAL_SERVER_ERROR",
});
Expand Down
10 changes: 4 additions & 6 deletions server/controllers/obtain-token-controller.js
Expand Up @@ -5,7 +5,7 @@ import qs from "qs";

import config from "../config.json";
import defaultConfig from "../utils/default-config";
import logInternalError from "../utils/log-internal-error";
import Logger from "../utils/logger";

const sendCookies = (username, response, conf, res) => {
// save token in signed cookie
Expand Down Expand Up @@ -50,9 +50,8 @@ const obtainToken = (req, res) => {
return sendCookies(username, response, conf, res);
})
.catch((error) => {
if (error.response && error.response.status === 500)
logInternalError(error);
console.log(`status code: ${error.response.status}`);
Logger.error(error);
Logger.warn(`status code: ${error.response.status}`);
try {
// inactive user recognized
if (error.response.status === 401) {
Expand All @@ -64,8 +63,7 @@ const obtainToken = (req, res) => {
.type("application/json")
.send(error.response.data);
} catch (err) {
logInternalError(error);
console.error(err);
Logger.error(error);
return res.status(500).type("application/json").send({
detail: "Internal server error",
});
Expand Down
7 changes: 3 additions & 4 deletions server/controllers/password-change-controller.js
Expand Up @@ -5,7 +5,7 @@ import qs from "qs";

import config from "../config.json";
import defaultConfig from "../utils/default-config";
import logInternalError from "../utils/log-internal-error";
import Logger from "../utils/logger";

const passwordChange = (req, res) => {
const reqOrg = req.params.organization;
Expand Down Expand Up @@ -44,16 +44,15 @@ const passwordChange = (req, res) => {
.send(response.data);
})
.catch((error) => {
if (error.response && error.response.status === 500)
logInternalError(error);
Logger.error(error);
// forward error
try {
res
.status(error.response.status)
.type("application/json")
.send(error.response.data);
} catch (err) {
logInternalError(error);
Logger.error(error);
res.status(500).type("application/json").send({
detail: "Internal server error",
});
Expand Down
7 changes: 3 additions & 4 deletions server/controllers/password-reset-confirm-controller.js
Expand Up @@ -4,7 +4,7 @@ import qs from "qs";

import config from "../config.json";
import defaultConfig from "../utils/default-config";
import logInternalError from "../utils/log-internal-error";
import Logger from "../utils/logger";

const passwordResetConfirm = (req, res) => {
const reqOrg = req.params.organization;
Expand Down Expand Up @@ -41,16 +41,15 @@ const passwordResetConfirm = (req, res) => {
.send(response.data);
})
.catch((error) => {
if (error.response && error.response.status === 500)
logInternalError(error);
Logger.error(error);
// forward error
try {
res
.status(error.response.status)
.type("application/json")
.send(error.response.data);
} catch (err) {
logInternalError(error);
Logger.error(error);
res.status(500).type("application/json").send({
detail: "Internal server error",
});
Expand Down
7 changes: 3 additions & 4 deletions server/controllers/password-reset-controller.js
Expand Up @@ -4,7 +4,7 @@ import qs from "qs";

import config from "../config.json";
import defaultConfig from "../utils/default-config";
import logInternalError from "../utils/log-internal-error";
import Logger from "../utils/logger";

const passwordReset = (req, res) => {
const reqOrg = req.params.organization;
Expand Down Expand Up @@ -37,16 +37,15 @@ const passwordReset = (req, res) => {
.send(response.data);
})
.catch((error) => {
if (error.response && error.response.status === 500)
logInternalError(error);
Logger.error(error);
// forward error
try {
res
.status(error.response.status)
.type("application/json")
.send(error.response.data);
} catch (err) {
logInternalError(error);
Logger.error(error);
res.status(500).type("application/json").send({
detail: "Internal server error",
});
Expand Down
7 changes: 3 additions & 4 deletions server/controllers/registration-controller.js
Expand Up @@ -6,7 +6,7 @@ import qs from "qs";

import config from "../config.json";
import defaultConfig from "../utils/default-config";
import logInternalError from "../utils/log-internal-error";
import Logger from "../utils/logger";

const registration = (req, res) => {
const reqOrg = req.params.organization;
Expand Down Expand Up @@ -78,16 +78,15 @@ const registration = (req, res) => {
.send();
})
.catch((error) => {
if (error.response && error.response.status === 500)
logInternalError(error);
Logger.error(error);
// forward error
try {
res
.status(error.response.status)
.type("application/json")
.send(error.response.data);
} catch (err) {
logInternalError(error);
Logger.error(error);
res.status(500).type("application/json").send({
detail: "Internal server error",
});
Expand Down
7 changes: 3 additions & 4 deletions server/controllers/user-radius-sessions-controller.js
Expand Up @@ -3,7 +3,7 @@ import cookie from "cookie-signature";
import merge from "deepmerge";
import config from "../config.json";
import defaultConfig from "../utils/default-config";
import logInternalError from "../utils/log-internal-error";
import Logger from "../utils/logger";

const getUserRadiusSessions = (req, res) => {
const reqOrg = req.params.organization;
Expand Down Expand Up @@ -43,16 +43,15 @@ const getUserRadiusSessions = (req, res) => {
.send(response.data);
})
.catch((error) => {
if (error.response && error.response.status === 500)
logInternalError(error);
Logger.error(error);
// forward error
try {
res
.status(error.response.status)
.type("application/json")
.send(error.response.data);
} catch (err) {
logInternalError(error);
Logger.error(error);
res.status(500).type("application/json").send({
response_code: "INTERNAL_SERVER_ERROR",
});
Expand Down
7 changes: 3 additions & 4 deletions server/controllers/validate-token-controller.js
Expand Up @@ -5,7 +5,7 @@ import qs from "qs";

import config from "../config.json";
import defaultConfig from "../utils/default-config";
import logInternalError from "../utils/log-internal-error";
import Logger from "../utils/logger";

const validateToken = (req, res) => {
const reqOrg = req.params.organization;
Expand Down Expand Up @@ -40,16 +40,15 @@ const validateToken = (req, res) => {
.send(response.data);
})
.catch((error) => {
if (error.response && error.response.status === 500)
logInternalError(error);
Logger.error(error);
// forward error
try {
res
.status(error.response.status)
.type("application/json")
.send(error.response.data);
} catch (err) {
logInternalError(error);
Logger.error(err);
res.status(500).type("application/json").send({
response_code: "INTERNAL_SERVER_ERROR",
});
Expand Down
9 changes: 5 additions & 4 deletions server/index.js
Expand Up @@ -5,9 +5,12 @@ import express from "express";
import net from "net";
import path from "path";
import routes from "./routes";
import morganMiddleware from "./morganMiddleware";
import logger from "./utils/logger";

const app = express();
app.use(compression());
app.use(morganMiddleware);
app.use(express.static(path.join(process.cwd(), "dist")));
app.use(cookieParser());
app.use(cookiesMiddleware());
Expand Down Expand Up @@ -43,15 +46,13 @@ const nextFreePort = (port, callback) => {
// If a port was passed as an argument, use that port
if (process.env.SERVER !== undefined) {
app.listen(process.env.SERVER, () => {
// eslint-disable-next-line no-console
console.log(`Server started on port ${process.env.SERVER}`);
logger.info(`Server started on port ${process.env.SERVER}`);
});
} else {
// Otherwise, find the next free port starting at the default port
nextFreePort(DEFAULT_PORT, (port) => {
app.listen(port, () => {
// eslint-disable-next-line no-console
console.log(`Server started on port ${port}`);
logger.info(`Server started on port ${port}`);
});
});
}
10 changes: 10 additions & 0 deletions server/loggerConfig.js
@@ -0,0 +1,10 @@
const logFilePath = {
all: process.env.ALL_LOG_FILE || "logs/all.log",
error: process.env.ERROR_LOG_FILE || "logs/error.log",
warn: process.env.WARN_LOG_FILE || "logs/warn.log",
info: process.env.INFO_LOG_FILE || "logs/info.log",
http: process.env.HTTP_LOG_FILE || "logs/http.log",
debug: process.env.DEBUG_LOG_FILE || "logs/debug.log",
codesankalp marked this conversation as resolved.
Show resolved Hide resolved
};

export default logFilePath;
19 changes: 19 additions & 0 deletions server/morganMiddleware.js
@@ -0,0 +1,19 @@
import morgan from "morgan";

import Logger from "./utils/logger";

const stream = {
write: (message) => Logger.http(message),
};

const skip = () => {
const env = process.env.NODE_ENV || "development";
return env !== "development";
};

const morganMiddleware = morgan(
":method :url :status :res[content-length] - :response-time ms",
{stream, skip},
);

export default morganMiddleware;