Compare commits

..

5 Commits
4.1.0 ... 4.2.0

Author SHA1 Message Date
Jose Bolos
3b76433cf3 Version 4.2.0 2022-03-30 17:19:08 +01:00
Jose Bolos
f3462f0c1e Bump webservice, deps, and linter configuration
* Bump webservice to require the latest 4.0.1 version
* Bump other dependencies
* Update linter conf to v2 which avoids the "Unsupported engine" warning when using node 12
* Keep all other devdependencies as they are so they stay consistent with the other repos
2022-03-30 18:16:25 +02:00
Jose Bolos
9dbee59746 Add request logging using morgan
This commit adds request logging to the app using morgan.

Every request will now be logged not one but twice: one when the request is received, and a second time when the response is sent.

The response logging also prints out the time elapsed in processing the request, which will be useful to debug performance issues (calls to the dashboard home are currently taking 4 - 15s on a populated database).

The new code uses a tiny middleware that uses nanoid to generate a random request id that can be used to match requests in the logs.

This logging will help us determine which requests are successful, which requests are slow, and establish what requests may have contributed to causing an application crash, making future debugging easier.
2022-03-08 11:19:15 +01:00
Jose Bolos
321d7bb6ba Split initApp in different functions
This makes the function easier to understand and fixes eslint complaints
about the function having too many statements.
2022-03-07 15:55:34 +01:00
Jose Bolos
4fd73bcf2f Make .editorconfig consistent between repos 2022-03-03 13:59:11 +00:00
4 changed files with 89 additions and 20 deletions

View File

@@ -5,9 +5,19 @@ root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_size = 4
indent_style = tab
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
indent_style = spaces
trim_trailing_whitespace = false
[*.yml]
indent_style = space
indent_size = 2
[package.json]
indent_style = space
indent_size = 2

View File

@@ -1,5 +1,10 @@
# Changelog
## 4.2.0 (2022-03-30)
* Add request logging for easier debugging
* Dependencies update
## 4.1.0 (2021-11-26)
* Add support for new WCAG 2.1 rules and remove all references to Section 508.

78
app.js
View File

@@ -20,6 +20,8 @@ const createClient = require('pa11y-webservice-client-node');
const EventEmitter = require('events').EventEmitter;
const express = require('express');
const hbs = require('express-hbs');
const morgan = require('morgan');
const {nanoid} = require('nanoid');
const http = require('http');
const pkg = require('./package.json');
@@ -35,14 +37,57 @@ function initApp(config, callback) {
}
const app = new EventEmitter();
app.address = null;
app.express = express();
app.server = http.createServer(app.express);
app.webservice = createClient(webserviceUrl);
loadMiddleware(app);
// View engine
loadViewEngine(app, config);
// Load routes
loadRoutes(app, config);
// Error handling
loadErrorHandling(app, config, callback);
}
// Get default configurations
function defaultConfig(config) {
if (typeof config.noindex !== 'boolean') {
config.noindex = true;
}
if (typeof config.readonly !== 'boolean') {
config.readonly = false;
}
return config;
}
function loadMiddleware(app) {
// Compression
app.express.use(compression());
// Adds an ID to every request, used later for logging
app.express.use(addRequestId);
// Logging middleware
morgan.token('id', request => {
return request.id;
});
// Log the start of all HTTP requests
const startLog = '[:date[iso] #:id] Started :method :url for :remote-addr';
// Immediate: true is required to log the request
// before the response happens
app.express.use(morgan(startLog, {immediate: true}));
// Log the end of all HTTP requests
const endLog = '[:date[iso] #:id] Completed :status :res[content-length] in :response-time ms';
app.express.use(morgan(endLog));
// Public files
app.express.use(express.static(`${__dirname}/public`, {
maxAge: (process.env.NODE_ENV === 'production' ? 604800000 : 0)
@@ -53,8 +98,9 @@ function initApp(config, callback) {
app.express.use(bodyParser.urlencoded({
extended: true
}));
}
// View engine
function loadViewEngine(app, config) {
app.express.engine('html', hbs.express4({
extname: '.html',
contentHelperName: 'content',
@@ -89,10 +135,16 @@ function initApp(config, callback) {
response.locals.host = request.hostname;
next();
});
}
// Load routes
function loadRoutes(app, config) {
// Because there's some overlap between the different routes,
// they have to be loaded in a specific order in order to avoid
// passing mongo the wrong id which would result in
// "ObjectID generation failed." errors (e.g. #277)
require('./route/index')(app);
require('./route/result/download')(app);
if (!config.readonly) {
require('./route/new')(app);
require('./route/task/delete')(app);
@@ -101,12 +153,14 @@ function initApp(config, callback) {
require('./route/task/ignore')(app);
require('./route/task/unignore')(app);
}
// Needs to be loaded after `/route/new`
require('./route/task/index')(app);
// Needs to be loaded after `/route/task/edit`
require('./route/result/index')(app);
}
// Error handling
function loadErrorHandling(app, config, callback) {
app.express.get('*', (request, response) => {
response.status(404);
response.render('404');
@@ -129,16 +183,14 @@ function initApp(config, callback) {
app.address = `http://${address.address}:${address.port}`;
callback(error, app);
});
}
// Get default configurations
function defaultConfig(config) {
if (typeof config.noindex !== 'boolean') {
config.noindex = true;
}
if (typeof config.readonly !== 'boolean') {
config.readonly = false;
}
return config;
// Express middleware
function addRequestId(request, response, next) {
// Create a random request (nano)id, 10 characters long
// Nano ids are [0-9A-Za-z_-] so chance of collision is 1 in 64^10
// If a site has so much traffic that this chance is too high
// we probably have worse things to worry about
request.id = nanoid(10);
next();
}

View File

@@ -1,6 +1,6 @@
{
"name": "pa11y-dashboard",
"version": "4.1.0",
"version": "4.2.0",
"private": true,
"description": "Pa11y Dashboard is a visual web interface to the Pa11y accessibility reporter",
"keywords": [
@@ -24,16 +24,18 @@
"node": ">=12 <16"
},
"dependencies": {
"body-parser": "~1.19.0",
"body-parser": "~1.19.2",
"compression": "~1.7.4",
"express": "~4.17.1",
"express": "~4.17.3",
"express-hbs": "~2.4.0",
"http-headers": "~3.0.2",
"kleur": "~4.1.4",
"moment": "~2.29.1",
"pa11y-webservice": "~4.0.0",
"morgan": "~1.10.0",
"nanoid": "~3.3.2",
"pa11y-webservice": "~4.0.1",
"pa11y-webservice-client-node": "~3.0.0",
"underscore": "~1.13.1"
"underscore": "~1.13.2"
},
"devDependencies": {
"bower": "^1.8.13",
@@ -41,7 +43,7 @@
"eslint": "^7.27.0",
"less": "^3.11.1",
"mocha": "^8.4.0",
"pa11y-lint-config": "^1.2.1",
"pa11y-lint-config": "^2.0.0",
"proclaim": "^3.6.0",
"request": "^2.88.2",
"uglify-js": "^3.11.0"