Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Winston's audit Files are created even when no logs are printed #378

Open
hakunamatata97k opened this issue Aug 20, 2023 · 2 comments
Open

Comments

@hakunamatata97k
Copy link

hakunamatata97k commented Aug 20, 2023

I'm currently using the following NPM packages to create my custom logger, Winston and Winston-daily-rotate-file.

The problem:

The <hash>.json are created regardless of the existance of the <info|error-[Date]>.log files.

What does the code look like:

I have the following code in logger.js :

import  *  as  winston  from  'winston';
import  'winston-daily-rotate-file';

//function is used in other place to get a date formated string. is there a way to get string back from winston logger?
function logWithTimestamp(message) {
	return `[${new Date().toISOString().replace('T', ' ').slice(0, 19)} ${message}]`;
}

//To account for https://github.com/winstonjs/winston/issues/614
const infoFilter = winston.format((info) => {
	return info.level === 'info' ? info : false;
});
function myFilter (func) {
	const filters = [];
	if (func)
		filters.push(func());

	return winston.format.combine(
		...filters,
		winston.format.errors({ stack: true }),
		winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
		winston.format.json()
	)
}
const logger = winston.createLogger({
	level: 'info', // Minimum log level to be recorded
	transports: [
		// Log errors to error.log file
		new winston.transports.DailyRotateFile({
			level: 'error',
			filename: 'logs/error-%DATE%.log',
                        lazy: true, //EDIT 1:this had no effect.
			datePattern: 'YYYY-MM-DD',
			maxSize: '10m', // Max size of log file
			maxFiles: '14d', // Keep logs for 14 days
			format: myFilter(),
		}),
		// Log info messages to info.log file
		new winston.transports.DailyRotateFile({
			level: 'info',
			filename: 'logs/info-%DATE%.log',
                        lazy: true, //EDIT 1:this had no effect.
			datePattern: 'YYYY-MM-DD',
			maxSize: '10m',
			maxFiles: '14d',
			format: myFilter(infoFilter)
		}),
	],
});

export {logger, logWithTimestamp}

In my index.js I import it as import {logger} from "./logger.js";

What I tried:

I think it's a bit due to the fact of me declaring it as const that will get called upon the program start.
Thus, I tried this:

`logger.js`

....
let logger;
function getLoggerInstance() {
    if (!logger) {
       logger = winston.createLogger({
          level: 'info', // Minimum log level to be recorded
          transports: [
             // Log errors to error.log file
             new winston.transports.DailyRotateFile({
                level: 'error',
                filename: 'logs/error-%DATE%.log',
                datePattern: 'YYYY-MM-DD',
                maxSize: '10m', // Max size of log file
                maxFiles: '14d', // Keep logs for 14 days
                format: myFilter(),
             }),
             // Log info messages to info.log file
             new winston.transports.DailyRotateFile({
                level: 'info',
                filename: 'logs/info-%DATE%.log',
                datePattern: 'YYYY-MM-DD',
                maxSize: '10m',
                maxFiles: '14d',
                format: myFilter(infoFilter)
             }),
          ],
       });
    }
    return logger;
}
export {getLoggerInstance, logWithTimestamp}
.... 

In index.js :

import { getLoggerInstance} from "./logger.js";
//const logger = getLoggerInstance(); // initializing the logger at top level causes the same problem. 

Then is changed the export in logger.js to export {getLoggerInstance as logger, logWithTimestamp} and in index.js I would have to constantly use logger().info(); to print, which is highly impractical in my opinion but kind of solves the problem.

Do you know how I could either invoke the creation of <hash>.json upon first logger.<info() | debug()> call or achieve the same behavior?

Please let me know, and thanks in advance.

EDIT 1:

Based on the comment from @Nol-go in #291 and the new introduction of the lazy option I modified the code to include it. Yet it still produces the same behaviour. Any suggestions are more than welcome :)

Image from the IDE view:

Untitled2

With or without the lazy option the audit files are being created on initialization, and with or without lazy the *.logs file are not initialized when nothing is logged. :/ sooo i dunno.

@hakunamatata97k
Copy link
Author

Edited the issue description to include the usage of the lazy option. Look up :)

@hugo-daclon
Copy link

hugo-daclon commented Aug 21, 2023

So what you could try as a temporary fixup is to create a script that erases files that are empty an run it with a cron module like node-schedule.

You could also try to implement MattBerter's solution locally in your node_modules folder, but it wouldn't work if you build the dependencies from scratch on your prod environment.

Last solution if it's really urgent, fork the project, implement his solution and use that fork in your package.json (I know it's possible but not how to do it so -> google if you have questions on that)

As for why the lazy option does not work, you would need to go into the transport code to check how they manage the options.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants