diff --git a/packages/app-desktop/package-lock.json b/packages/app-desktop/package-lock.json index 1ff71a9c0..dbe6ed734 100644 --- a/packages/app-desktop/package-lock.json +++ b/packages/app-desktop/package-lock.json @@ -1,6 +1,6 @@ { "name": "@joplin/app-desktop", - "version": "1.5.12", + "version": "1.6.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/packages/lib/Logger.ts b/packages/lib/Logger.ts index 9a5ab940c..5b3fb901d 100644 --- a/packages/lib/Logger.ts +++ b/packages/lib/Logger.ts @@ -1,6 +1,7 @@ const moment = require('moment'); const time = require('./time').default; const { FsDriverDummy } = require('./fs-driver-dummy.js'); +const { sprintf } = require('sprintf-js'); export enum TargetType { Database = 'database', @@ -24,6 +25,12 @@ interface Target { prefix?: string; path?: 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 { @@ -173,9 +180,25 @@ class Logger { if (level == LogLevel.Warn) fn = 'warn'; if (level == LogLevel.Info) fn = 'info'; const consoleObj = target.console ? target.console : console; - const prefixItems = [moment().format('HH:mm:ss')]; - if (targetPrefix) prefixItems.push(targetPrefix); - const items = [`${prefixItems.join(': ')}:`].concat(...object); + let items:any[] = []; + + 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); } else if (target.type == 'file') { const timestamp = moment().format('YYYY-MM-DD HH:mm:ss'); diff --git a/packages/server/src/app.ts b/packages/server/src/app.ts index 675e23bfb..dacd721e7 100644 --- a/packages/server/src/app.ts +++ b/packages/server/src/app.ts @@ -38,7 +38,9 @@ shimInit(); let appLogger_: LoggerWrapper = null; function appLogger(): LoggerWrapper { - if (!appLogger_) appLogger_ = Logger.create('App'); + if (!appLogger_) { + appLogger_ = Logger.create('App'); + } return appLogger_; } @@ -68,10 +70,15 @@ app.use(async (ctx: Koa.Context) => { throw new ErrorNotFound(); } } 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; - const responseFormat = routeResponseFormat(match); + const responseFormat = routeResponseFormat(match, ctx.path); if (responseFormat === RouteResponseFormat.Html) { ctx.response.set('Content-Type', 'text/html'); @@ -86,7 +93,7 @@ app.use(async (ctx: Koa.Context) => { } else { // JSON ctx.response.set('Content-Type', 'application/json'); 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; ctx.response.body = r; } @@ -102,8 +109,11 @@ async function main() { await fs.mkdirp(config().logDir); Logger.fsDriver_ = new FsDriverNode(); const globalLogger = new Logger(); - globalLogger.addTarget(TargetType.File, { path: `${config().logDir}/app.txt` }); - globalLogger.addTarget(TargetType.Console); + // globalLogger.addTarget(TargetType.File, { path: `${config().logDir}/app.txt` }); + 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); const pidFile = argv.pidfile as string; diff --git a/packages/server/src/utils/routeUtils.ts b/packages/server/src/utils/routeUtils.ts index 8f22112fa..5d4a4c5cf 100644 --- a/packages/server/src/utils/routeUtils.ts +++ b/packages/server/src/utils/routeUtils.ts @@ -145,11 +145,13 @@ export function parseSubPath(p: string): SubPath { return output; } -export function routeResponseFormat(match: MatchedRoute): RouteResponseFormat { - if (!match) return RouteResponseFormat.Json; - if (match.route.responseFormat) return match.route.responseFormat; - const s = match.basePath ? match.basePath : match.subPath.raw; - return s.indexOf('api') === 0 ? RouteResponseFormat.Json : RouteResponseFormat.Html; +export function routeResponseFormat(match: MatchedRoute, rawPath:string): RouteResponseFormat { + if (match && match.route.responseFormat) return match.route.responseFormat; + + let path = rawPath; + 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 {