logger.ts 3.1 KB

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