I am using Winston.js to log some information in a Javascript application. The problem is that the log level should be hidden in the printed log.
Instead of having something like this:
info: some pretty and cool log message
I need to have something like this:
some pretty and cool log message
I have a look at the Winston main page, but I did not find anything.
You need to use custom format:
const { createLogger, format, transports } = require('winston');
const winston = createLogger({
level: 'info',
transports: [
new transports.Console({
level: 'info',
format: format.combine(
format.colorize(),
format.printf(
(info) => {
// return `${info.level}: ${info.message}`;
return `${info.message}`;
})
)
}),
]
});
winston.info('Hello world');
winston.log('info', 'Hello world 2');
//or you can use wrapper to easy replace console.log
const logger = {
log:(msg) => {
winston.info(msg);
}
}
logger.log('Hello world 3');
Scrabbling the unit test of the library, I found this one: Custom formatter. Basically, declaring a custom formatter for a log level, you can basically do everything you want with the text that will be write to the log.
To write the log message only without any log level information, redefine the formatter for a log in the following way.
var winston = require('winston');
var logger = new (winston.Logger)({
transports: [
new (winston.transports.Console)({
level: 'info',
pattern: /info\:/,
formatter: function(params) {
return undefined !== params.message ? params.message : "";
}
})
]
});
The above example defines a console logger that prints only the message for the logs of level info, without any additional information.
Hope it helps.
Related
Hey everyone i need help setting up my Winston logging config.
I am migrating an existing project with 300 + console.logs to winston and now the values of the logs are not printed anymore.
I researched online and only found hacky solutions that didn't work for me.
Any help is appreciated.
This is my logger config
// logger config
const winston = require('winston')
const { combine, timestamp, colorize, align, printf } = winston.format
const logger = winston.createLogger({
// level: process.env.LOG_LEVEL || 'info',
level: 'silly',
format: combine(
colorize({ all: true }),
timestamp({
format: 'YYYY-MM-DD hh:mm:ss',
}),
align(),
printf((info) => `[${info.timestamp}] ${info.level}: ${info.message}`)
), transports: [new winston.transports.Console()],
})
module.exports = logger
This is how the console log was before:
console.log('active jobs : ',
(await queue.getActive()).length)
Output:
active jobs : 12
This is how it is now:
logger.info(
'active jobs : ',
(await queue.getActive()).length
)
Output:
[2022-05-23 03:57:29] info: active jobs :
I would appreciate if there is a possibility without changing the console.logs since they are so many.
when we run the yeoman it is asking to add input one by one, is there anyway to give all input one go ? or programically?
for Example :
yo azuresfguest
it is asking to add 5 inputs, which i want to give one time, so i can run in CI/CD system
Thanks,
There isn't a general way, unfortunately. The specific generator would need to allow it.
I think it is deserving of a feature request on the Yeoman project, which I've logged here.
As a cumbersome workaround, you can create your own generator which re-uses an existing generator. The TypeScript code below gives an example; I'm using this approach to automate my CI process.
Add option to constructor:
constructor(args: string, opts: Generator.GeneratorOptions) {
super(args, opts);
...
this.option("prompts-json-file", {
type: String,
default: undefined,
description: "Skips prompting; uses file contents. Useful for automation",
});
}
Use the option:
async prompting() {
if (this.options["prompts-json-file"] !== undefined) {
this.answers = new Answers(JSON.parse(
fs.readFileSync(this.options["prompts-json-file"]).toString()
));
}
else {
this.answers = ...
}
}
Unfortunately this does bypass prompt validation so you'd need to separately ensure your file contains valid values.
Using it is relatively simple:
yo my-generator --prompts-json-file ./prompts.json
This should be accomplished using Yeomans storage API and a .yo-rc.json file:
https://yeoman.io/authoring/storage.html
I used to use a self defined option to make that optional similar to the approach from #BjornO
constructor(args, opts) {
super(args, opts);
// This method adds support for a `--yo-rc` flag
this.option('yo-rc', {
desc: 'Read and apply options from .yo-rc.json and skip prompting',
type: Boolean,
defaults: false
});
}
initializing() {
this.skipPrompts = false;
if (this.options['yo-rc']) {
const config = this.config.getAll();
this.log(
'Read and applied the following config from ' +
chalk.yellow('.yo-rc.json:\n')
);
this.log(config);
this.log('\n');
this.templateProps = {
projectName: config.projectName,
};
this.skipPrompts = true;
}
}
prompting() {
if (!this.skipPrompts) {
// Have Yeoman greet the user.
this.log(
yosay(
`Yo, welcome to the ${superb()} ${chalk.yellow(
'Baumeister'
)} generator!`
)
);
const prompts = [
{
type: 'input',
name: 'projectName',
message: 'What’s the name of your project?',
// Default to current folder name
default: _s.titleize(this.appname)
}
];
return this.prompt(prompts).then(props => {
this.templateProps = {
projectName: props.projectName
};
});
}
}
See https://github.com/micromata/generator-baumeister/blob/master/app/index.js#L20-L69 for the whole generator code and https://github.com/micromata/generator-baumeister/blob/master/\_\_tests__/yo-rc.json for the corresponding .yo-rc.json file.
I'm attempting to use Winston and winston-daily-rotate-file to log all my console/log output from a node.js server to a single file that will (hopefully) get rotated daily at midnight.
The issue I'm encountering is that unhandled exceptions seem to generate a new log file rather than write to the existing one. See the example code below for the duplication behaviour. How do I get all output to be saved to a single logfile as well as output to the console? At present, the console side of things appears to be fine but feel free to point out anything obvious that I'm missing.
OS: Win 10
node: v12.16.0
npm: v6.13.4
winston: v3.2.1
winston-daily-rotate-file: v4.4.2
const winston = require('winston');
const DailyRotateFile = require('winston-daily-rotate-file');
const path = require('path');
var logger = new (winston.createLogger)({
transports: [
new (winston.transports.Console)({
format: winston.format.combine(
winston.format.timestamp(),
winston.format.colorize({ all: true }),
winston.format.printf((info) => {
const {
timestamp, level, message
} = info;
return `${timestamp} - ${level}: ${message}`;
}),
),
handleExceptions: true
}),
new DailyRotateFile({
name: 'file',
datePattern: 'YYYY-MM-DDTHH-mm-ss',
handleExceptions: true,
format: winston.format.combine(
winston.format.timestamp(),
winston.format.printf((info) => {
const {
timestamp, level, message
} = info;
return `${timestamp} - ${level}: ${message}`;
}),
),
filename: path.join(__dirname, 'logs', '%DATE%.log')
}),
]
});
logger.info("This is an info message");
logger.error("This is an error message");
setTimeout(() => {throw new Error('oh dear!')}, 5000);
My issue was caused by the datePattern option. winston-daily-rotate-file uses this pattern to determine the frequency of file rotation. As I had included seconds in the pattern it was looking for a file with the current timestamp (to the nearest second) and creating it before writing to file.
To get daily files I just needed to change
datePattern: 'YYYY-MM-DDTHH-mm-ss'
to
datePattern: 'YYYY-MM-DD'
I am writing a module for logging in Nodejs using Winston. I am using a custom format and initialize my logger like this:
const logger = createLogger({
format: combine(
format.timestamp(),
format.printf(msg => `${JSON.stringify({timestamp: msg.timestamp,
shortmessage: msg.message,
level: msg.level,
source: config.programName,
file: __filename,
line: '' })}`) // how to get this?
),
transports: [new (transports.Console)({
level: config.logLevel, // logs up to specified level
})]
});
module.exports = {
error: function (message) {
logger.error(message);
},
info: function (message) {
logger.info(message);
},
debug: function (message) {
logger.debug(message);
}
};
As mentioned in the comment, I also need to include line number in my log. I did some research and found some workarounds (1, 2, 3), but it seems they can't be used in my case, as I use a custom format, which should be specified during the logger creation time and line number can be retrieved later.
I was thinking to use Winston's label feature, but it seems labels can contain only static data.
How can this be solved? Any ideas.
So Im using winston-daily-rotate-file.
In app.js I have:
var logger = require('./logger');
and then:
logger.info("logging to info");
logger.error("logging to error");
In logger/index.js I have:
var error_transport = new winston.transports.DailyRotateFile({
filename: '../logs/error',
datePattern: 'yyyy-MM-dd.',
prepend: true,
level: 'error',
name: 'error'
});
var info_transport = new winston.transports.DailyRotateFile({
filename: '../logs/info',
datePattern: 'yyyy-MM-dd.',
prepend: true,
level: 'info',
name: 'info'
});
var logger = new (winston.Logger)({
transports: [
error_transport,
info_transport
]
});
module.exports = logger;
What happens is that the file
logs/DATE_error
contains:
logging to error
BUT: the file
logs/DATE_info
contains:
logging to info
logging to error
Why is the info file also including logs from error?
You can read about Winston's logging levels here: Logging Levels
The basic reason that info is including logs from error is that "levels" with a higher priority number will always log messages for any level "below" them in priority. See the example under Using Logging Levels
var logger = new (winston.Logger)({
transports: [
new (winston.transports.Console)({ level: 'warn' }),
new (winston.transports.File)({ filename: 'somefile.log', level: 'error' })
]
});
logger.debug("Will not be logged in either transport!");
logger.transports.console.level = 'debug';
logger.transports.file.level = 'verbose';
logger.verbose("Will be logged in both transports!");