This is my winston logger -
var winston = require('winston')
var logger = new (winston.Logger)({
transports: [
new (winston.transports.File)({
// log which takes care of all the MAS scoring - node clusters and servers
filename: './test.log',
level: 'info',
json: true,
eol: 'rn'
})
]
})
And when I run the actual logger:
logger.info('hi', 'it meeeeee')
logger.info('hi', 'it youuuuuu')
It prints out like this in the test.log file -
{"level":"info","message":"hi it meeeeee","timestamp":"2016-08-18T08:42:01.768Z"}rn{"level":"info","message":"hi it youuuuuu","timestamp":"2016-08-18T08:42:01.770Z"}rn
And I want it to be like this:
{"level":"info","message":"hi it meeeeee","timestamp":"2016-08-18T08:42:01.768Z"}
{"level":"info","message":"hi it youuuuuu","timestamp":"2016-08-18T08:42:01.770Z"}
How is this possible? I have read this question Node.js winston logger; How to start from a newline when insert log into log file? - however it does not solve the issue in my case.
I.e. if I open in Notepad ++, command line or Sublime text I still get the same issue.
Try this eol: \r\n
Look official documentation
Related
I'm building a Node.js application and can't figure out how to configure the winston logger the right way.
What I would like to acchieve:
My application should have 6 custom logging levels (fatal, error, warning, status, info & debug). For those levels, there should be methods such as logger.status(message, ...details).
I would like to be able to pass additional JS objects (details) after the message for debugging/evaluation purposes.
Logs should be printed to the console
All console outputs should look the following:
[ISO Date String] [Level in uppercase]: [Log Message]
fatal & error logs should be printed in red
debug & info logs should only be printed if a constant (e.g. this.debug related to my class) is set to true. debug logs should be printed in yellow.
Logs of all levels should be written to a DailyRotateFile, in the same format as above (except for the colors of course).
Logs should be stored in a MongoDB with the following properties: date, level, message, details (containing all objects passed), label (specifies from which part of the log was sent, to be set manually).
What I've done so far:
As recommended, I've extended the default winston class using TypeScript in order to add methods for my specific logging levels:
import winston = require('winston');
interface Logger extends winston.Logger {
fatal: winston.LeveledLogMethod;
error: winston.LeveledLogMethod;
warning: winston.LeveledLogMethod;
status: winston.LeveledLogMethod;
info: winston.LeveledLogMethod;
debug: winston.LeveledLogMethod;
}
From this interface, I've created an instance like so:
this.logger = <Logger>winston.createLogger({
levels: {
fatal: 0,
error: 1,
warning: 2,
status: 3,
info: 4,
debug: 5
},
level: 'debug',
transports: [
new winston.transports.Console({
}),
new winston.transports.DailyRotateFile({
filename: 'cplus-%DATE%.log',
dirname: this.logsDir,
datePattern: 'YYYY-MM-DD-HH-mm'
}),
new winston.transports.MongoDB({
db: this.dbClient
})
]
});
Basic logging to the console & file using the new methods works fine, for example
this.logger.fatal('Connection to database ' + this.dbUrl + ' failed, cannot start', err);
creates the following output:
{"message":"Connection to database mongodb://localhost:27017 failed, cannot startAuthentication failed.","name":"MongooseServerSelectionError","reason": ...
Now, how do I acchieve the rest, such as formatting and correct storing in MongoDB? I've tried a few different things using the preset Winston formats, with no success.
Best regards!
I am sending logs directly to Elasticsearch from a Node.js app using the winston and winston-elasticsearch packages. Elasticsearch 7.5.1, Logstash & Kibana 7.5.1 were deployed on a remote server using Docker Compose.
Problem 1: After running the node.js file that sends 2 log messages to Elasticsearch, the program does not automatically exit to return to the terminal. Using Node.js v12.6.0 on Mac OS X Mojave 10.14.6.
Problem 2: After these 2 log messages were sent to Elasticsearch, they can be viewed using a web browser at http://<example.com>:9200/logs-2020.02.01/_search.
{"took":5,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{"value":2,"relation":"eq"},"max_score":1.0,"hits":[{"_index":"logs-2020.02.01","_type":"_doc","_id":"85GgA3ABiaPPk4as1pEc","_score":1.0,"_source":{"#timestamp":"2020-02-02T02:00:35.789Z","message":"a debug message","severity":"debug","fields":{}}},{"_index":"logs-2020.02.01","_type":"_doc","_id":"9JGgA3ABiaPPk4as1pEc","_score":1.0,"_source":{"#timestamp":"2020-02-02T02:00:35.791Z","message":"an info log","severity":"info","fields":{}}}]}}
However, these logs do not show up on Kibana, such as the Logs section at https://<example.com>/app/infra#/logs/stream?_g=().
Any idea how to get the logs to also show up on Kibana? Also, why is the Node.js app not exiting after sending the log messages?
Thank you!
Node.js App
const winston = require('winston');
const ElasticsearchWinston = require('winston-elasticsearch');
const options = {
console: {
level: 'debug',
handleExceptions: true,
json: false,
colorize: true
},
elasticsearch: {
level: 'debug',
clientOpts: {
node: 'http://user:pass#example.com:9200',
log: 'debug',
maxRetries: 2,
requestTimeout: 10000,
sniffOnStart: false,
}
}
}
var logger = winston.createLogger({
exitOnError: false,
transports: [
new winston.transports.Console(options.console),
new ElasticsearchWinston(options.elasticsearch)
]
});
logger.debug('a debug message');
logger.info('an info log');
I'm not a node.js expert so I will only focus on the kibana issue. The Logs app is not meant to be for "custom" logs/indices like yours.
As stated in the documentation (https://www.elastic.co/guide/en/kibana/current/xpack-logs.html):
The Logs app in Kibana enables you to explore logs for common servers, containers, and services.
The logs app is for monitoring your infrastructure and ELK-Services, e.g. through certain Beats-modules (e.g. the Elasticsearch-, Kibana- and Logstash-Module of Filebeat).
Also from the docs (https://www.elastic.co/guide/en/kibana/current/xpack-logs-configuring.html):
The default source configuration for logs is specified in the Logs app settings in the Kibana configuration file. The default configuration uses the filebeat-* index pattern to query the data.
This explains why you dont see any data in the logs app since your indices use the 'logs-*' index pattern.
Long story short:
To view the documents in your log-* indices, you need to open the Discovery (first icon on the left sidebar in Kibana) and select the index pattern you already have set up. This is the appropriate way of searching your application data in Kibana.
I hope I could help you.
I am creating full mean stack app with
NodeJs , Angular 6 , ExpressJs and MongoDB
I have managed to create a server and its working perfectly, instead of using console.log when logging errors in my app I have decided to use Winston Logger here is what I have now
Server side
var appRoot = require('app-root-path');
var winston = require('winston');
// define the custom settings for each transport (file, console)
var options = {
file: {
level: 'info',
filename: `${appRoot}/logs/app.log`,
handleExceptions: true,
json: true,
maxsize: 5242880, // 5MB
maxFiles: 5,
colorize: false,
},
console: {
level: 'debug',
handleExceptions: true,
json: false,
colorize: true,
},
};
// instantiate a new Winston Logger with the settings defined above
const logger = winston.createLogger({
transports: [
new winston.transports.File(options.file),
new winston.transports.Console(options.console)
],
exitOnError: false, // do not exit on handled exceptions
});
// create a stream object with a 'write' function that will be used by `morgan`
logger.stream = {
write: function (message, encoding) {
// use the 'info' log level so the output will be picked up by both transports (file and console)
logger.info(message);
},
};
module.exports = logger;
Note: Winston in server side works perfectly
Client-Side
I want to use winston in my client side angular 6 app .
Example: in one of my components i have this.
import * as logger from "winston";
.........
this.activeRouter.params.subscribe((params) => {
// tslint:disable-next-line:prefer-const
let id = params['id'];
this.moviesService.getReview(id)
.subscribe(review => {
console.log(review);
this.review = review;
});
});
As you can see I am using console.log(review) , Instead of console log I would like to use Winston .
How to use Winston logger in client-side ? am newbie to all this stuff any help will be apreciated.
Yeah it is possible, however default transport for browser is very limited. I recommend to use https://www.npmjs.com/package/winston-transport-browserconsole
npm install winston-transport-browserconsole -S
It is easy to use and supports logging json objects:
import * as winston from "winston";
import BrowserConsole from 'winston-transport-browserconsole';
const level = "debug";
winston.configure({
transports: [
new BrowserConsole(
{
format: winston.format.simple(),
level,
},
),
],
});
winston.debug("DEBUG ", {a: 1, b: "two"});
Yes - it can (technically) be used in the browser. Should it be? Almost definitely not (sadly). Winston is a fantastic logger for node. But, emphasis on "for node". If you want to use it on the client, you would need to add a bunch of node polyfills in addition to winston itself, which is very large relative to other client loggers. Between winston and those polyfills you are going to significantly increase the size of your artifact. Also, just fyi webpack 5 removed those node polyfills, so you would need to add them back manually.
According to this ticket: https://github.com/winstonjs/winston/issues/287 it's almost ready for browser use? Or mostly ready? It sounds like they recently started supporting logging in a browser environment.
I am using NodeJS/React/Express/winston in conjunction. Here are the versions:
react & react-router-dom: 15.6.1
express: 4.15.3
node: 8.4.0
npm: 5.3.0
winston: 2.3.1
express-winston: 2.4.0
I instantiate my logger as such:
var logger = new (winston.Logger) ({
transports: [
new(winston.transports.File) ({
filename: 'log.txt',
handleExceptions: true,
prettyPrint: true
})
], exitOnError: false
});
I have created log.txt so the directory and file both exist.
At this point, I can go to my server and everything renders successfully as before.
If I add any calls to my logger, such as:
logger.info("Hello World!");
my application no longer renders, however I do not see any errors in the Console.
I have tried this as well with express-winston to log middleware requests which has the same outcome: logging works in the console for express-winson, but not when I want to write to an external file.
I just cannot seem to locate the source of this problem, it has absolutely baffled me. Please let me know if you see any red flags or have suggestions for how to debug this problem. Thank you very much for your time and help!
****** UPDATE ******
I have found that if I use:
try {
logger.info("hello");
}
catch(e) { alert(e); }
I get this message:
TypeError: fs.stat is not a function
I cannot find anything online that can fix this. Please advise
I'm using winston to log all output from my node js app to a log file, but when I run the app as a crontab job, it does not write anything to the log file. This is setup of my winston transport:
var winston = require('winston'),
getTimeStamp = function() {
return new Date().toString();
}
if(process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'test') {
winston.add(winston.transports.File, {
filename: environment.logFileName,
maxsize: 1024*1024*10, //10MB
timestamp: getTimeStamp(),
colorize: true
});
winston.remove(winston.transports.Console);
}
winston.exitOnError = false;
Winston seems to work fine if I direct all my output do a cron.log file, like this:
0 12 * * 1 /apps/accounting/server/Invoice_Worker/test.sh >> /var/log/cron.log
or If I use console.log to do all the output.
I also tried doing this and did not fix the issue:
0 12 * * 1 /apps/accounting/server/Invoice_Worker/test.sh >> /dev/null 2>&1
winston is not writing to my test or production logs regardless of the environment I run the app in. Any advice would help please. Thanks!
The issue has been solved. I did mistake of not providing absolute paths to my log files inside my node server and crontab always require absolute paths