1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-01-11 18:24:43 +02:00

Server: Improved logging and error handling

This commit is contained in:
Laurent Cozic 2020-12-28 15:15:30 +00:00
parent 29177330b0
commit 2fda067034
4 changed files with 50 additions and 15 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "@joplin/app-desktop", "name": "@joplin/app-desktop",
"version": "1.5.12", "version": "1.6.0",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {

View File

@ -1,6 +1,7 @@
const moment = require('moment'); const moment = require('moment');
const time = require('./time').default; const time = require('./time').default;
const { FsDriverDummy } = require('./fs-driver-dummy.js'); const { FsDriverDummy } = require('./fs-driver-dummy.js');
const { sprintf } = require('sprintf-js');
export enum TargetType { export enum TargetType {
Database = 'database', Database = 'database',
@ -24,6 +25,12 @@ interface Target {
prefix?: string; prefix?: string;
path?: string; path?: string;
source?: string; source?: string;
// Default message format
format?: string;
// If specified, will use this as format if it's an info message
formatInfo?: string;
} }
export interface LoggerWrapper { export interface LoggerWrapper {
@ -173,9 +180,25 @@ class Logger {
if (level == LogLevel.Warn) fn = 'warn'; if (level == LogLevel.Warn) fn = 'warn';
if (level == LogLevel.Info) fn = 'info'; if (level == LogLevel.Info) fn = 'info';
const consoleObj = target.console ? target.console : console; const consoleObj = target.console ? target.console : console;
const prefixItems = [moment().format('HH:mm:ss')]; let items:any[] = [];
if (targetPrefix) prefixItems.push(targetPrefix);
const items = [`${prefixItems.join(': ')}:`].concat(...object); if (target.format) {
const format = level === LogLevel.Info && target.formatInfo ? target.formatInfo : target.format;
const s = sprintf(format, {
date_time: moment().format('YYYY-MM-DD HH:mm:ss'),
level: Logger.levelIdToString(level),
prefix: targetPrefix || '',
message: '',
});
items = [s.trim()].concat(...object);
} else {
const prefixItems = [moment().format('HH:mm:ss')];
if (targetPrefix) prefixItems.push(targetPrefix);
items = [`${prefixItems.join(': ')}:`].concat(...object);
}
consoleObj[fn](...items); consoleObj[fn](...items);
} else if (target.type == 'file') { } else if (target.type == 'file') {
const timestamp = moment().format('YYYY-MM-DD HH:mm:ss'); const timestamp = moment().format('YYYY-MM-DD HH:mm:ss');

View File

@ -38,7 +38,9 @@ shimInit();
let appLogger_: LoggerWrapper = null; let appLogger_: LoggerWrapper = null;
function appLogger(): LoggerWrapper { function appLogger(): LoggerWrapper {
if (!appLogger_) appLogger_ = Logger.create('App'); if (!appLogger_) {
appLogger_ = Logger.create('App');
}
return appLogger_; return appLogger_;
} }
@ -68,10 +70,15 @@ app.use(async (ctx: Koa.Context) => {
throw new ErrorNotFound(); throw new ErrorNotFound();
} }
} catch (error) { } catch (error) {
appLogger().error(error); if (error.httpCode >= 400 && error.httpCode < 500) {
appLogger().error(error.httpCode + ': ' + `${ctx.request.method} ${ctx.path}` + ' : ' + error.message);
} else {
appLogger().error(error);
}
ctx.response.status = error.httpCode ? error.httpCode : 500; ctx.response.status = error.httpCode ? error.httpCode : 500;
const responseFormat = routeResponseFormat(match); const responseFormat = routeResponseFormat(match, ctx.path);
if (responseFormat === RouteResponseFormat.Html) { if (responseFormat === RouteResponseFormat.Html) {
ctx.response.set('Content-Type', 'text/html'); ctx.response.set('Content-Type', 'text/html');
@ -86,7 +93,7 @@ app.use(async (ctx: Koa.Context) => {
} else { // JSON } else { // JSON
ctx.response.set('Content-Type', 'application/json'); ctx.response.set('Content-Type', 'application/json');
const r: any = { error: error.message }; const r: any = { error: error.message };
if (env == 'dev' && error.stack) r.stack = error.stack; if (env === 'dev' && error.stack) r.stack = error.stack;
if (error.code) r.code = error.code; if (error.code) r.code = error.code;
ctx.response.body = r; ctx.response.body = r;
} }
@ -102,8 +109,11 @@ async function main() {
await fs.mkdirp(config().logDir); await fs.mkdirp(config().logDir);
Logger.fsDriver_ = new FsDriverNode(); Logger.fsDriver_ = new FsDriverNode();
const globalLogger = new Logger(); const globalLogger = new Logger();
globalLogger.addTarget(TargetType.File, { path: `${config().logDir}/app.txt` }); // globalLogger.addTarget(TargetType.File, { path: `${config().logDir}/app.txt` });
globalLogger.addTarget(TargetType.Console); globalLogger.addTarget(TargetType.Console, {
format: '%(date_time)s: [%(level)s] %(prefix)s: %(message)s',
formatInfo: '%(date_time)s: %(prefix)s: %(message)s',
});
Logger.initializeGlobalLogger(globalLogger); Logger.initializeGlobalLogger(globalLogger);
const pidFile = argv.pidfile as string; const pidFile = argv.pidfile as string;

View File

@ -145,11 +145,13 @@ export function parseSubPath(p: string): SubPath {
return output; return output;
} }
export function routeResponseFormat(match: MatchedRoute): RouteResponseFormat { export function routeResponseFormat(match: MatchedRoute, rawPath:string): RouteResponseFormat {
if (!match) return RouteResponseFormat.Json; if (match && match.route.responseFormat) return match.route.responseFormat;
if (match.route.responseFormat) return match.route.responseFormat;
const s = match.basePath ? match.basePath : match.subPath.raw; let path = rawPath;
return s.indexOf('api') === 0 ? RouteResponseFormat.Json : RouteResponseFormat.Html; if (match) path = match.basePath ? match.basePath : match.subPath.raw;
return path.indexOf('api') === 0 || path.indexOf('/api') === 0 ? RouteResponseFormat.Json : RouteResponseFormat.Html;
} }
export function findMatchingRoute(path: string, routes: Routes): MatchedRoute { export function findMatchingRoute(path: string, routes: Routes): MatchedRoute {