v1.18.x
Julian Lam 9 years ago
parent 458c930bb9
commit 149565169b

@ -0,0 +1,64 @@
"use strict";
/*global config, define, app, socket, ajaxify, bootbox, templates, Chart, utils */
define('admin/advanced/errors', ['Chart'], function(Chart) {
var Errors = {};
Errors.init = function() {
var notFoundCanvas = document.getElementById('not-found'),
tooBusyCanvas = document.getElementById('toobusy'),
dailyLabels = utils.getDaysArray();
dailyLabels.length = 7;
if (utils.isMobile()) {
Chart.defaults.global.showTooltips = false;
}
var data = {
'not-found': {
labels: dailyLabels,
datasets: [
{
label: "",
fillColor: "rgba(186,139,175,0.2)",
strokeColor: "rgba(186,139,175,1)",
pointColor: "rgba(186,139,175,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(186,139,175,1)",
data: ajaxify.data.analytics['not-found']
}
]
},
'toobusy': {
labels: dailyLabels,
datasets: [
{
label: "",
fillColor: "rgba(151,187,205,0.2)",
strokeColor: "rgba(151,187,205,1)",
pointColor: "rgba(151,187,205,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(151,187,205,1)",
data: ajaxify.data.analytics['toobusy']
}
]
}
};
notFoundCanvas.width = $(notFoundCanvas).parent().width();
tooBusyCanvas.width = $(tooBusyCanvas).parent().width();
new Chart(notFoundCanvas.getContext('2d')).Line(data['not-found'], {
responsive: true,
animation: false
});
new Chart(tooBusyCanvas.getContext('2d')).Line(data['toobusy'], {
responsive: true,
animation: false
});
};
return Errors;
});

@ -1,7 +1,7 @@
"use strict";
/*global config, define, app, socket, ajaxify, bootbox, templates, Chart, utils */
/*global config, define, app, socket, ajaxify, bootbox, templates, utils */
define('admin/manage/category-analytics', [], function() {
define('admin/manage/category-analytics', ['Chart'], function(Chart) {
var CategoryAnalytics = {};
CategoryAnalytics.init = function() {

@ -187,4 +187,11 @@ var db = require('./database');
}, callback);
};
Analytics.getErrorAnalytics = function(callback) {
async.parallel({
'not-found': async.apply(Analytics.getDailyStatsForSet, 'analytics:errors:404', Date.now(), 7),
'toobusy': async.apply(Analytics.getDailyStatsForSet, 'analytics:errors:503', Date.now(), 7)
}, callback);
};
}(exports));

@ -14,6 +14,7 @@ var adminController = {
},
events: require('./admin/events'),
logs: require('./admin/logs'),
errors: require('./admin/errors'),
database: require('./admin/database'),
postCache: require('./admin/postCache'),
plugins: require('./admin/plugins'),

@ -0,0 +1,20 @@
'use strict';
var async = require('async');
var meta = require('../../meta'),
analytics = require('../../analytics');
var errorsController = {};
errorsController.get = function(req, res) {
async.parallel({
'not-found': async.apply(meta.errors.get),
analytics: async.apply(analytics.getErrorAnalytics)
}, function(err, data) {
res.render('admin/advanced/errors', data);
});
};
module.exports = errorsController;

@ -373,12 +373,14 @@ Controllers.handle404 = function(req, res) {
} else if (isLanguage.test(req.url)) {
res.status(200).json({});
} else if (req.path.startsWith(relativePath + '/uploads') || (req.get('accept') && req.get('accept').indexOf('text/html') === -1) || req.path === '/favicon.ico') {
meta.errors.log404(req.path || '');
res.sendStatus(404);
} else if (req.accepts('html')) {
if (process.env.NODE_ENV === 'development') {
winston.warn('Route requested but not found: ' + req.url);
}
meta.errors.log404(req.path.replace(/^\/api/, '') || '');
res.status(404);
if (res.locals.isAPI) {

@ -24,6 +24,7 @@ var async = require('async'),
require('./meta/sounds')(Meta);
require('./meta/settings')(Meta);
require('./meta/logs')(Meta);
require('./meta/errors')(Meta);
require('./meta/tags')(Meta);
require('./meta/dependencies')(Meta);
Meta.templates = require('./meta/templates');

@ -0,0 +1,36 @@
'use strict';
var async = require('async'),
winston = require('winston'),
validator = require('validator');
var db = require('../database'),
analytics = require('../analytics');
module.exports = function(Meta) {
Meta.errors = {};
Meta.errors.log404 = function(route, callback) {
callback = callback || function() {};
route = route.replace(/\/$/, ''); // remove trailing slashes
analytics.increment('errors:404');
db.sortedSetIncrBy('errors:404', 1, route, callback);
};
Meta.errors.get = function(callback) {
db.getSortedSetRevRangeByScoreWithScores('errors:404', 0, -1, '+inf', '-inf', function(err, data) {
data = data.map(function(nfObject) {
nfObject.value = validator.escape(nfObject.value);
return nfObject;
});
callback(null, data);
});
};
Meta.errors.clear = function(callback) {
console.log('clear errors');
callback();
};
};

@ -302,6 +302,7 @@ middleware.privateUploads = function(req, res, next) {
middleware.busyCheck = function(req, res, next) {
if (global.env === 'production' && (!meta.config.hasOwnProperty('eventLoopCheckEnabled') || parseInt(meta.config.eventLoopCheckEnabled, 10) === 1) && toobusy()) {
analytics.increment('errors:503');
res.status(503).type('text/html').sendFile(path.join(__dirname, '../../public/503.html'));
} else {
next();

@ -82,6 +82,7 @@ function addRoutes(router, middleware, controllers) {
router.get('/advanced/database', middlewares, controllers.admin.database.get);
router.get('/advanced/events', middlewares, controllers.admin.events.get);
router.get('/advanced/logs', middlewares, controllers.admin.logs.get);
router.get('/advanced/errors', middlewares, controllers.admin.errors.get);
router.get('/advanced/post-cache', middlewares, controllers.admin.postCache.get);
router.get('/development/logger', middlewares, controllers.admin.logger.get);

@ -0,0 +1,61 @@
<div class="row">
<div class="col-lg-9">
<div class="row">
<div class="col-sm-6 text-center">
<div class="panel panel-default">
<div class="panel-body">
<div><canvas id="not-found" height="250"></canvas></div>
</div>
<div class="panel-footer"><small><strong>Figure 1</strong> &ndash; <code>404 Not Found</code> events per day</small></div>
</div>
</div>
<div class="col-sm-6 text-center">
<div class="panel panel-default">
<div class="panel-body">
<div><canvas id="toobusy" height="250"></canvas></div>
</div>
<div class="panel-footer"><small><strong>Figure 2</strong> &ndash; <code>503 Service Unavailable</code> events per day</small></div>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading"><i class="fa fa-exclamation-triangle"></i> 404 Not Found</div>
<div class="panel-body">
<table class="table table-striped">
<thead>
<th>Route</th>
<th>Count</th>
</thead>
<tbody>
<!-- BEGIN not-found -->
<tr>
<td>{../value}</td>
<td>{../score}</td>
</tr>
<!-- END not-found -->
<!-- IF !not-found.length -->
<tr>
<td colspan="2">
<div class="alert alert-success">
Hooray! There are no routes that were not found.
</div>
</td>
</tr>
<!-- ENDIF !not-found.length -->
</tbody>
</table>
</div>
</div>
</div>
<div class="col-lg-3 acp-sidebar">
<div class="panel panel-default">
<div class="panel-heading">Manage Error Log</div>
<div class="panel-body">
<div class="btn-group-vertical btn-block" role="group">
<button class="btn btn-info" data-action="export"><i class="fa fa-download"></i> Export Error Log (CSV)</button>
<button class="btn btn-danger" data-action="clear"><i class="fa fa-trash"></i> Clear Error Log</button>
</div>
</div>
</div>
</div>
</div>

@ -95,6 +95,7 @@
<li><a href="{relative_path}/admin/advanced/database">Database</a></li>
<li><a href="{relative_path}/admin/advanced/events">Events</a></li>
<li><a href="{relative_path}/admin/advanced/logs">Logs</a></li>
<li><a href="{relative_path}/admin/advanced/errors">Errors</a></li>
<li><a href="{relative_path}/admin/advanced/post-cache">Post Cache</a></li>
<!-- IF env -->
<li><a href="{relative_path}/admin/development/logger">Logger</a></li>
@ -247,6 +248,7 @@
<li><a href="{relative_path}/admin/advanced/database">Database</a></li>
<li><a href="{relative_path}/admin/advanced/events">Events</a></li>
<li><a href="{relative_path}/admin/advanced/logs">Logs</a></li>
<li><a href="{relative_path}/admin/advanced/errors">Errors</a></li>
<li><a href="{relative_path}/admin/advanced/post-cache">Post Cache</a></li>
<!-- IF env -->
<li><a href="{relative_path}/admin/development/logger">Logger</a></li>

Loading…
Cancel
Save