# Generate Custom Output File


This feature has been introduced in vREST NG CLI v1.8.0.

In this guide, we will look at, how you may generate the custom log output from the vrest-ng-cli utility as per your customized needs. We provide all the available data related to test cases and test suites to the custom logger by emitting various events.

First let's see the various command options to use the custom logger:

vrest-ng-cli run --projectdir=/path/to/your/project/directory 

Please note that your custom logger can emit the output in any format, so you may change the value of --logfilepath as per your own needs.

Now, let us look at the basic script of custom-logger.js file:

const path = require('path');
const fs = require('fs');

  let CustomLogger = function(emitter, options){
    //default log file path
    let defaultLogFilePath = options.cwd + path.sep + 'vrest_logs' + path.sep + 'log.json';

    //options.filePath - log file path provided through options
    this.logFilePath = options.filePath || defaultLogFilePath;

    //Root Object in which we will fill data on various events
    this.mainObject = {};
    //The following events will occur in the following order
    //You may remove some of the events if you don't need any specific data
    emitter.on('pre-runner', this.init, this);
    emitter.on("pre-test-run", this.preTestRun, this);
    emitter.on("pre-test-suite", this.preTestSuite, this);
    emitter.on("pre-test-case", this.preTestCase, this);
    emitter.on("pre-test-case-iteration", this.preTestCaseIteration, this);
    emitter.on("post-test-case-iteration", this.postTestCaseIteration, this);
    emitter.on("post-test-case", this.postTestCase, this);
    emitter.on("test-case-execution-interrupted", this.onTestCaseExecutionInterrupted, this);
    emitter.on("post-test-suite", this.postTestSuite, this);
    emitter.on("post-test-run", this.postTestRun, this);
    emitter.on('post-runner', this.over, this);

  //this method will be executed whenever a test run is initiated
  CustomLogger.prototype.init = function(){

  //this method will be executed before the test run execution starts
  CustomLogger.prototype.preTestRun = function(){

  //This method will be invoked before each test suite execution
  CustomLogger.prototype.preTestSuite = function(preTestSuiteData){


  //This method will be invoked before each test case execution
  CustomLogger.prototype.preTestCase = function(preTestCaseData){


  //This method will be invoked before each test case iteration execution
  CustomLogger.prototype.preTestCaseIteration = function(preTestIterationData){


  //This method will be invoked after each test case iteration execution
  CustomLogger.prototype.postTestCaseIteration = function(postTestIterationData){


  //This method will be invoked after each test case execution
  CustomLogger.prototype.postTestCase = function(postTestCaseData){


  //This method will be invoked whenever there are some abnormal test interruptions (on uncaught exceptions)
  CustomLogger.prototype.onTestCaseExecutionInterrupted = function(testCaseError){


  //This method will be invoked after each test suite execution
  CustomLogger.prototype.postTestSuite = function(postTestSuiteData){

  //This method will be invoked after the test run execution completes
  CustomLogger.prototype.postTestRun = function(postTestRunData){


  //This method will be invoked at the end
  //we can return a promise, so that the main method will wait for us to complete
  CustomLogger.prototype.over = function(){
    return new Promise((resolve, reject) => {
      try {
        fs.writeFileSync(this.logFilePath, JSON.stringify(this.mainObject, null, 2));
        return resolve();
      } catch (err) {
        return reject(err);

  return CustomLogger;

In the above script, you may implement various event listeners to fill the mainObject and in the over method, we are writing that mainObject to the log file.