Winston logger profiler time unit - node.js

I'm using winston logger profiling.
my question is how can I change the time unit of the profiler.
My code:
this.logger.profile(`some ${jobId}`);
// do the job ....
this.logger.profile(`some ${jobId}`);
In the result I see:
{ ...,"message": "some 1", "durationMs":2500 ... }
My question is how (is) it possible to configure the time unit from ms to seconds/minuets etc...
So that I'll see
{ ...,"message": "some 1", "durationSeconds: 2.5" ... }

The answer is unfortunately no: winston doesn't provide an option of providing the duration in a unit other than ms, see:
https://github.com/winstonjs/winston/blob/master/lib/winston/profiler.js#L47

Related

log4js - node package - not writing to file

I am novice to nodejs and wanted my node app to log to a file as well as console.
Here is my code structure:
fpa_log4j.json:
{
"appenders": {
"fpa_file": {
"type": "file",
"filename": "fpa.log",
"maxLogSize": 10485760,
"backups": 10,
"compress": true
},
"screen": {
"type": "stdout",
"layout": {
"type": "coloured"
}
}
},
"categories": {
"default": {
"appenders": [
"fpa_file",
"screen"
],
"level": "trace"
}
}
}
config.js
var LOG4J_CFG = 'config/fpa_log4j.json';
var fs = require('fs');
var log4js = require('log4js');
var path = require('path');
LOG4J_CFG = path.resolve(LOG4J_CFG);
log4js.configure(JSON.parse(fs.readFileSync(LOG4J_CFG, 'utf8')));
....
....
module.exports = {
log4js,
....
....
}
app.js
var cfg = require('./config');
var log = cfg.log4js.getLogger("appMain");
log.info('FPA program STARTED!');
OUTPUT
[2017-12-04T03:20:17.791] [INFO] appMain - FPA program STARTED!
However the log file seems to be empty:
dir fpa.log
Volume in drive C is XXXXXXXXX
Volume Serial Number is XXXXXXXXXXXX
Directory of c:\fpaMain
12/04/2017 12:13 AM 0 fpa.log
1 File(s) 0 bytes
0 Dir(s) 12,242,776,064 bytes free
To be frank, I was able to make this work few days back. But then something got changed (alas, not able to recollect what it is!) I guess, and then logging into the file stopped.
Ok. So I figured it out finally. Sharing it here for the sake of others. Here it comes:
There were few more lines in the app.js (which were removed for clarity) and the app was in fact crashing immediately after the log.info() statement. And I was expecting the statements to appear in the log file as it appeared on the console. But then, I failed to realize that, unlike other programming languages, nodejs has got the powerful feature of parallel processing by birth itself (which in fact was one of the core reasons for my love towards it :)).
So in my case, due to its unparallel feature of parallel processing, nodejs just fired the log statement and went on processing other statements. And, when it crashed, it took down the whole program with it. Since writing to the console was way much faster than IO (for the obvious reasons!!), it showed up on the screen faster. However before it could write to the file system the app got crashed, ending up nothing being written to the file!
Lesson Learned:
Always remember that nodejs === parallel processing
For any IO related issues like the above, ensure that the program runs to complete or at least for some more time before it crashes,
thus providing enough time for the IO to complete.

How to stop testRunner in case one of the http APIs HTTP Status Code is not 200

I am running on an CI machine my soapUI automation solution, invoked by testRunner.sh.
is is invoked as following:
/Projects/SoapUI-5.2.1/bin/testrunner.sh ~/sautomation_work/Automation_Project.xml
I would like to stop the whole process in case a certain API http status code is not 200.
Any ideas ?
currently, the only way I can do this is by invoking the last test suite "FinalReport" and disable rest of the test scripts currently available in the running test suite.
The code is as following:
public testSuiteStop() {
def properties = new com.eviware.soapui.support.types.StringToObjectMap();
def reportTestCase = testRunner.testCase.testSuite.project.getTestSuiteByName("Report").getTestCaseByName("FinalReport");
reportTestCase.run(properties, true);
def testSuite = context.testCase.testSuite;
def totalTestCases = testSuite.getTestCases().size();
for(testCaseItem in (0..totalTestCases-1)) {
testSuite.getTestCaseAt(testCaseItem).setDisabled(true)
}
}
I have found a way to exit the current soapUI execution in case one of the critical test has already failed.
The idea is to disable the remaining test suites and test cases, and execute a "final" test suite that reports the failed test execution.
my code looks like this:
import com.eviware.soapui.impl.wsdl.WsdlProject;
import com.eviware.soapui.impl.wsdl.WsdlTestSuite;
import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
WsdlTestSuite testSuite = context.testCase.testSuite;
WsdlProject project = context.testCase.getProject();
// Disable remaining test cases in the current test suite.
for (WsdlTestCase testCase in testSuite.testCaseList) {
testCase.setDisabled(true);
}
// Disable rest of the test suites
for (WsdlTestSuite testSuiteName in project.testSuiteList) {
testSuiteName.setDisabled(testSuiteName.name != "LastTestSuite");
}

npm winston set log level for basic logging instance

Setting winston log level to 'debug' in 'easy mode' was not well documented so I've shown an example below (and will submit a PR soon).
the answer is winston.level = 'debug'
I want to use the winston logging package in a node script and not bother with any config, just be able to call winston.debug, winston.info, winston.error and then pass in the log level as a command line param. The docs for 'easy mode' did not include how to set log level so I've shown it below.
The code:
var winston = require('winston');
winston.transports.Console.level = "debug";
winston.log("error", "error test 1");
winston.log("info", "info test 1");
winston.log("debug", "debug test 1");
winston.level = "debug";
winston.log("error", "error test 2");
winston.log("info", "info test 2");
winston.log("debug", "debug test 2");
Will output:
error: error test 1
info: info test 1
error: error test 2
info: info test 2
debug: debug test 2
Hope this helps
the answer is winston.level = 'debug'

How to generate multiple reports with mocha?

I want to have the following reports:
coverage
spec
xunit
all running in a single mocha execution from my grunt
Currently - I have to run the tests 3 times, each time to generate a different report(!).
So I use grunt-mocha-test with 2 configuration where only the reporter is different (once xunit-file and once spec).
And then I have grunt-mocha-istanbul that runs the tests yet again,and generates the coverage report.
I tried using
{
options: {
reporters : ['xunit-file', 'spec']
}
}
for grunt-mocha-test at least to bring it down to 2, but that doesn't work as well.
reading grunt-mocha-istanbul documentation, i can't seem to find any info about reporter configuration.
How can I resolve this?
Maybe this can help:
https://github.com/glenjamin/mocha-multi
AFAIK this is not supported in Mocha yet, but it is on its way:
https://github.com/mochajs/mocha/pull/1360
Hope this helps,
György
I ran into the same problem recently, and found nothing after looking around SO as well as GH issues. It seems that topic of officially supporting multiple reporters are getting postponed over and over.
Having said that having a custom solution is quite easy, assuming the reporters you want to combine already exist. What I did is to create a small and naive custom reporter, and used the reporter in .mocharc.js config.
// junit-spec-reporter.js
const mocha = require("mocha");
const JUnit = require("mocha-junit-reporter");
const Spec = mocha.reporters.Spec;
const Base = mocha.reporters.Base;
function JunitSpecReporter(runner, options) {
Base.call(this, runner, options);
this._junitReporter = new JUnit(runner, options);
this._specReporter = new Spec(runner, options);
return this;
}
JunitSpecReporter.prototype.__proto__ = Base.prototype;
module.exports = JunitSpecReporter;
// .mocharc.js
module.exports = {
reporter: './junit-spec-reporter.js',
reporterOptions: {
mochaFile: './tests-results/results.xml'
}
};
The example above shows how to use both spec and junit reporter.
More info on custom reporter: https://mochajs.org/api/tutorial-custom-reporter.html
Note that this is just a proof of concept and can be made prettier and more robust using more generic approach (and TypeScript).
Update 14.9.2021
I have created a utility package for this: https://www.npmjs.com/package/#netatwork/mocha-utils
For simultaneously reporting for spec and x-unit, there's also an NPM package called spec-xunit-file.
In grunt:
grunt.initConfig({
mochaTest: {
test: {
options: {
reporter: 'spec-xunit-file',
...
},
...
}
}
...
});

Is there an equivalent of log.IsDebugEnabled in Winston?

Is there an equivalent of log.IsDebugEnabled in Winston?
I want to use this to skip expensive logging code in a production environment but have it execute in development.
For example:
if(winston.isDebugEnabled){
// Call to expensive dump routine here
dump();
}
Checking winston.debug just checks whether the method is defined, not whether it is enabled.
Many thanks!
Edit: Added code example.
I've added a method to my logger to achieve just that:
logger.isLevelEnabled = function(level) {
return _.any(this.transports, function(transport) {
return (transport.level && this.levels[transport.level] <= this.levels[level])
|| (!transport.level && this.levels[this.level] <= this.levels[level]);
}, this);
};
This goes through each of your logger's transports and checks whether it 'wants' to log the specified level.
Note _.any is lodash, you can replace with for loop.
I'm sure you'd be able to get that directly from winston, but if you want to have different logging levels for different environments, you should pass these in when you're creating the winston.logger.
For example:
// default log file level is info (which is the lowest by default)
var logFileLevel = 'info';
if (process.env.NODE_ENV == 'production') {
// only write logs with a level of 'error' or above when in production
logFileLevel = 'error';
}
var logger = new (winston.Logger)({
transports: [
new (winston.transports.File)({
filename: '/var/log/node-logger.log',
level: logFileLevel
})
]
});
It's also useful to switch out the transports. You might want to use the Console transport whilst in development, and the File transport when in production for example.
More documentation on all this on the winston readme.
Try
if ( logger.levels[logger.level] >= logger.levels['debug'] ) {
// expensive calculation here
logger.debug(...)
}
Since Winston 3.1.0 (PR), you can use the Logger functions isLevelEnabled(string) & isXXXEnabled() for this.

Resources