Adonis Logger format

Looking for some additional information tips on formatting adonis.log.

I’m following the docs (winston and adonis), but for some reason when I open the log file up, the second param in Logger(msg, data) prints before the first param, and %j (or any others %s , etc), is included in the message string).

Is this right? Based on the samples I’ve seen in winston’s docs, it doesn’t look right… How can I change this? what did I do wrong.

./app/validators/UnitUpdate.js

const Logger = use('Logger')

class UnitUpdate {
...
async fails(messages) {
    const request = this.ctx.request
   
    Logger.info('request details %j', messages)

    return this.ctx.response.status(422).json({
      messages,
    })
  }
...
}

./tmp/adonis.log

{"0":{"message":"Min_temp provided was not within the expected range","field":"min_temp","validation":"range"},"level":"error","message":"    Request failures: %j"}
1 Like

Okay, so…

I dug a little further into winston’s docs, ./project-dir/node_modules/@adonisjs/framework/src/Logger and solved my issue. However I did it in, what I would consider, not the neatest way possible. At this point I’m looking for suggestions on how to improve this, and keep things tidy.

These additions were all made in ./config/app.js:

...
const { format } = require('winston');
const { combine, timestamp, prettyPrint, colorize, printf, splat, align } = format;
const myFormat = printf(({ level, message, timestamp }) => {
  return `${timestamp} ${level}: ${message}`;
});

module.exports = {
...
logger: {
   transport: 'file',
   file: {
      driver: 'file',
      name: 'vega-server',
      filename: 'adonis.log',
      level: 'info',
      format: combine(
        align(),
        splat(),
        colorize(),
        timestamp(),
        prettyPrint(),
        myFormat
      )
    }
},
...
}

1 Like

For anyone who might come across this, I was able to improve my initial solution using: https://github.com/thetutlage/adonis-extend-logger

My extension is included below:

'use strict'

const { ServiceProvider } = require('@adonisjs/fold')
const DefaultFileDriver = require('@adonisjs/framework/src/Logger/Drivers/File')
const winston = require('winston');
const { combine, timestamp, prettyPrint, colorize, printf, splat, align } = winston.format
const path = require('path')
const _ = require('lodash')
const Helpers = use('Helpers')

class LogExtProvider extends ServiceProvider {
  /**
   * Register namespaces to the IoC container
   *
   * @method register
   *
   * @return {void}
   */
  register () {
    this.app.extend('Adonis/Src/Logger', 'loggerext', () => {
      class LoggerExt extends DefaultFileDriver {
        setConfig (config) {
          this.config = Object.assign({}, {
            name: 'adonis-app',
            filename: 'adonis.log',
            level: 'info'
          }, config)
          
          const myFormat = printf(({ level, message, timestamp }) => {
            return `${timestamp} ${level}: ${message}`;
          })
          const format = combine(
            align(),
            splat(),
            timestamp(),
            prettyPrint(),
            myFormat
          )
          delete this.config.format
      
          /**
           * If filename is not absolute, save it inside the tmp path
           * of adonis-app.
           */
          if (!path.isAbsolute(this.config.filename)) {
            this.config.filename = Helpers.tmpPath(this.config.filename)
          }
      
          /**
           * Creating new instance of winston with file transport
           */
          this.logger = winston.createLogger({
            levels: this.levels,
            format: format,
            transports: [new winston.transports.File(this.config)]
          })
        }

        log(level, msg, ...meta) {
            const levelName = _.findKey(this.levels, (num) => {
                return num === level
            })
            this.logger.log(levelName, `${msg}`, ...meta)
        }
      }

      return new LoggerExt()
    })
  }

  /**
   * Attach context getter when all providers have
   * been registered
   *
   * @method boot
   *
   * @return {void}
   */
  boot () {
    //
  }
}

module.exports = LogExtProvider