NodeJs Winston log line number - javascript

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.

Related

Winston not logging correct values

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.

Winston javascript logger is creating two separate log files. How do I log all entries into a single 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'

How to correctly configure unit tests for Probot with Scheduler Extension?

I am using the following minimal probot app and try to write Mocha unit tests for it.
Unfortunately, it results in the error below, which indicates that some of my setup for the private key or security tokens is not picked up.
I assume that the configuration with my .env file is correct since I do not get the same error when I start the probot via probot-run.js.
Are there any extra steps needed to configure probot when used with Mocha?
Any suggestions on why the use of the scheduler extension may result in such issue would be great.
Code and error below:
app.ts
import createScheduler from "probot-scheduler";
import { Application } from "probot";
export = (app: Application) => {
createScheduler(app, {
delay: !!process.env.DISABLE_DELAY, // delay is enabled on first run
interval: 24 * 60 * 60 * 1000 // 1 day
});
app.on("schedule.repository", async function (context) {
app.log.info("schedule.repository");
const result = await context.github.pullRequests.list({owner: "owner", repo: "test"});
app.log.info(result);
});
};
test.ts
import createApp from "../src/app";
import nock from "nock";
import { Probot } from "probot";
nock.disableNetConnect();
describe("my scenario", function() {
let probot: Probot;
beforeEach(function() {
probot = new Probot({});
const app = probot.load(createApp);
});
it("basic feature", async function() {
await probot.receive({name: "schedule.repository", payload: {action: "foo"}});
});
});
This unfortunately results in the following error:
Error: secretOrPrivateKey must have a value
at Object.module.exports [as sign] (node_modules/jsonwebtoken/sign.js:101:20)
at Application.app (node_modules/probot/lib/github-app.js:15:39)
at Application.<anonymous> (node_modules/probot/lib/application.js:260:72)
at step (node_modules/probot/lib/application.js:40:23)
at Object.next (node_modules/probot/lib/application.js:21:53)
Turns out that new Probot({}); as suggested in the documentation initializes the Probot object without any parameters (the given options object {} is empty after all).
To avoid the error, one can provide the information manually:
new Probot({
cert: "...",
secret: "...",
id: 12345
});

Workbox Service Worker with Background Sync module

I've been using Workbox for a few days and i correctly set it up for generating a service worker from a source and dont let Workbox generate it for me.
It works ok but now im trying to include the workbox-background-sync module for storing some failed POST requests and i cant get it to work.
After running the SW, i get "Uncaught TypeError: Cannot read property 'QueuePlugin' of undefined" on the first backgroundSync line (line number 9). This is the generated ServiceWorker file:
importScripts('workbox-sw.prod.v2.1.2.js');
importScripts('workbox-background-sync.prod.v2.0.3.js');
const workbox = new WorkboxSW({
skipWaiting: true,
clientsClaim: true
})
let bgQueue = new workbox.backgroundSync.QueuePlugin({
callbacks: {
replayDidSucceed: async(hash, res) => {
self.registration.showNotification('Background sync demo', {
body: 'Product has been purchased.',
icon: '/images/shop-icon-384.png',
});
},
replayDidFail: (hash) => {},
requestWillEnqueue: (reqData) => {},
requestWillDequeue: (reqData) => {},
},
});
const requestWrapper = new workbox.runtimeCaching.RequestWrapper({
plugins: [bgQueue],
});
const route = new workbox.routing.RegExpRoute({
regExp: new RegExp('^https://jsonplaceholder.typicode.com'),
handler: new workbox.runtimeCaching.NetworkOnly({requestWrapper}),
});
const router = new workbox.routing.Router();
router.registerRoute({route});
workbox.router.registerRoute(
new RegExp('.*\/api/catalog/available'),
workbox.strategies.networkFirst()
);
workbox.router.registerRoute(
new RegExp('.*\/api/user'),
workbox.strategies.networkFirst()
);
workbox.router.registerRoute(
new RegExp('.*\/api/security-element'),
workbox.strategies.networkOnly()
);
workbox.precache([]);
I've tried to load it with workbox.loadModule('workbox-background-sync'), a workaround i've found on github, but it still not working. Also, trying with
self.workbox = new WorkboxSW(), with the same faith.
P.S: Is there a way i can hook a function AFTER a strategy like networkFirst has failed and its going to respond with cache? because i want to know, if im getting a cached response i would like to tell the user that by modifying the incoming response and handle it later in Vue for example. Thanks for reading!
I solved it.. it was actually pretty silly, i was accesing the const workbox instead of instantiating a new workbox.backgroundSync, i fixed it by simply renaming the const workbox to const workboxSW

Hiding log-level in Winston logs

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.

Categories

Resources