Merge branch 'release/beta-10' into develop
[oweals/peertube.git] / server / helpers / logger.ts
1 // Thanks http://tostring.it/2014/06/23/advanced-logging-with-nodejs/
2 import * as mkdirp from 'mkdirp'
3 import * as path from 'path'
4 import * as winston from 'winston'
5 import { CONFIG } from '../initializers'
6
7 const label = CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT
8
9 // Create the directory if it does not exist
10 mkdirp.sync(CONFIG.STORAGE.LOG_DIR)
11
12 function loggerReplacer (key: string, value: any) {
13   if (value instanceof Error) {
14     const error = {}
15
16     Object.getOwnPropertyNames(value).forEach(key => error[ key ] = value[ key ])
17
18     return error
19   }
20
21   return value
22 }
23
24 const consoleLoggerFormat = winston.format.printf(info => {
25   let additionalInfos = JSON.stringify(info.meta || info.err, loggerReplacer, 2)
26   if (additionalInfos === undefined || additionalInfos === '{}') additionalInfos = ''
27   else additionalInfos = ' ' + additionalInfos
28
29   return `[${info.label}] ${info.timestamp} ${info.level}: ${info.message}${additionalInfos}`
30 })
31
32 const jsonLoggerFormat = winston.format.printf(info => {
33   return JSON.stringify(info, loggerReplacer)
34 })
35
36 const timestampFormatter = winston.format.timestamp({
37   format: 'YYYY-MM-DD HH:mm:ss.SSS'
38 })
39 const labelFormatter = winston.format.label({
40   label
41 })
42
43 const logger = winston.createLogger({
44   level: CONFIG.LOG.LEVEL,
45   format: winston.format.combine(
46     labelFormatter,
47     winston.format.splat()
48   ),
49   transports: [
50     new winston.transports.File({
51       filename: path.join(CONFIG.STORAGE.LOG_DIR, 'peertube.log'),
52       handleExceptions: true,
53       maxsize: 1024 * 1024 * 30,
54       maxFiles: 5,
55       format: winston.format.combine(
56         winston.format.timestamp(),
57         jsonLoggerFormat
58       )
59     }),
60     new winston.transports.Console({
61       handleExceptions: true,
62       format: winston.format.combine(
63         timestampFormatter,
64         winston.format.colorize(),
65         consoleLoggerFormat
66       )
67     })
68   ],
69   exitOnError: true
70 })
71
72 function bunyanLogFactory (level: string) {
73   return function () {
74     let meta = null
75     let args: any[] = []
76     args.concat(arguments)
77
78     if (arguments[ 0 ] instanceof Error) {
79       meta = arguments[ 0 ].toString()
80       args = Array.prototype.slice.call(arguments, 1)
81       args.push(meta)
82     } else if (typeof (args[ 0 ]) !== 'string') {
83       meta = arguments[ 0 ]
84       args = Array.prototype.slice.call(arguments, 1)
85       args.push(meta)
86     }
87
88     logger[ level ].apply(logger, args)
89   }
90 }
91 const bunyanLogger = {
92   trace: bunyanLogFactory('debug'),
93   debug: bunyanLogFactory('debug'),
94   info: bunyanLogFactory('info'),
95   warn: bunyanLogFactory('warn'),
96   error: bunyanLogFactory('error'),
97   fatal: bunyanLogFactory('error')
98 }
99 // ---------------------------------------------------------------------------
100
101 export {
102   timestampFormatter,
103   labelFormatter,
104   consoleLoggerFormat,
105   jsonLoggerFormat,
106   logger,
107   bunyanLogger
108 }