Crontab blocking winston to write to my log files - javascript

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

Related

Error running forever.js on Windows - "'C:\Program' is not recognized as an internal or external command, operable program or batch file"

I am trying to run forever.js via the Windows command prompt and I get the following output:
>npm i -g forever
/my-project>forever start index.js
Log output:
'C:\Program' is not recognized as an internal or external command, operable program or batch file
I think it's something to do with the PATH that forever is using for the node binary, but I don't know how to fix it...
EDIT: Forever is using the following command (which is surrounded by quotes " "):
"C:\Program Files\nodejs\node.exe"
If you type dir /x in the root of c:, you can see the short name of the directory.
So, try the following instead:
C:\PROGRA~1\nodejs\node.exe
installing forever version 1.0.0 solved the problem for me
i have the same problem with forever 2.0.0.
I use a workaround in "forever.js": (I start my app by "node forever.js" )
const configChild = {
//
// Basic configuration options
//
silent: true, // Silences the output from stdout and stderr in the parent process
'killTree': true, // Kills the entire child process tree on `exit`
....
}
// =======================================================
// **Workaround for Windows**
// =======================================================
if (process.platform === 'win32' && process.execPath == "C:\\Program Files\\nodejs\\node.exe") {
configChild.command = '"C:\\PROGRA~1\\nodejs\\node.exe"';
}
const child = new (forever.Monitor)('app.js', configChild);
....
child.start();

starting docker backend from electron-vue frontend

I am building an app based on electron vue. My electron app is supposed to start its backend running from a docker container. To do this I call a bash file with the docker run command in it.
const {spawn} = require('child_process')
const dckrrn = spawn('sh', dockercall)
dckrrn.stdout.on('data', (data) => {
console.log(`stdout: ${data}`)
})
dckrrn.stderr.on('data', (data) => {
console.log(`stderr: ${data}`)
})
dckrrn.on('close', (code) => {
console.log(`child process exited with code ${code}`)
})
Everything works fine in development mode but when I try it in my packaged app it complains:
stderr: pathtobashscript.sh line 13 docker: command not found.
It seems for some reason the spawned child process is unaware of the docker installation on the system. What am I doing wrong? What is the correct way to achieve this? Should I try the execfile function? Thanks for your time!
PS:
Sorry that I cannot provide you with a reproducible example, the total app with backend is around 7gb.
PPS:
some interesting sidenotes:
which docker
returns nothing, and:
pwd
returns: /
PPPS: I tried including the docker path at the beginning of my bash script but with no success:
PATH="/usr/local/bin/docker:${PATH}"
export PATH
4PS:
I managed to get the docker running by adding shell: true to the environment. The problem I have now is that the docker folder mappings do not work anymore. So I guess I also have to make them visible to the env somehow.
const {spawn} = require('child_process')
const dckrrn = spawn('sh', dockercall, {
env: {
shell: true
}
})
solved by adding shell: true to the env:
const {spawn} = require('child_process')
const dckrrn = spawn('sh', dockercall, {
env: {
shell: true
}
})

How to run a shell command from Grunt task function

I'm trying to move some icons in my app directory based on a function i have inside my Gruntfile.js. Would it be possible to do something like this? I've tried the following (going into dev or staging folder and copying all files to the previous directory), but coudn't get it to work. Thanks in advance.
grunt.registerTask('setAppIcon', 'Task that sets the app icon', function(environment) {
if (environment.toLowerCase() == "development") {
grunt.task.run(['exec:command:cd app/lib/extras/res/icon/ios/dev && cp -a . ../']);
} else if (environment.toLowerCase() == "staging") {
grunt.task.run(['exec:command:cd app/lib/extras/res/icon/ios/staging && cp -a . ../']);
}
});
Yes, it's possible to achieve your requirement, however, when you invoke the grunt.task.run command inside your function (i.e. custom task) you need to provide a reference to a task to run.
If you define a separate Target, (Let's call call them copy_dev and copy_staging - as shown in the example below), for each cd ... && cp ... command in the grunt-exec Task it should work successfully.
Gruntfile.js
The following Gruntfile.js gist shows how this can be achieved:
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-exec');
grunt.initConfig({
exec: {
copy_dev: {
cmd: 'cd app/lib/extras/res/icon/ios/dev && cp -a . ../'
},
copy_staging: {
cmd: 'cd app/lib/extras/res/icon/ios/staging && cp -a . ../'
}
}
});
grunt.registerTask('setAppIcon', 'Task that sets the app icon', function() {
var environment = process.env.NODE_ENV;
// Exit early if NODE_ENV variable has not been set.
if (!environment) {
grunt.log.writeln(
'\"setAppIcon\"" task failed - NODE_ENV has not been set.'['yellow']
)
return
}
if (environment.toLowerCase() == "development") {
grunt.task.run('exec:copy_dev');
grunt.log.writeln('>> Copying icons from \"dev\"...')
} else if (environment.toLowerCase() == "staging") {
grunt.task.run('exec:copy_staging');
grunt.log.writeln('>> Copying icons from \"staging\"...')
}
});
grunt.registerTask('default', [ 'setAppIcon' ]);
};
Additional notes
Inside the custom task/function named setAppIcon we obtain the current node environment using nodes builtin process.env
When running $ grunt via your CLI (using the gist shown above), and assuming your process.env.NODE_ENV variable has not been set, or it has possibly been unset by running $ unset NODE_ENV, you will see the following message:
"setAppIcon"" task failed - NODE_ENV has not been set.
However, if the process.env.NODE_ENV variable has been set to either development or staging the files will be copied as expected.
For example running either of the following via your CLI will work successfully:
$ export NODE_ENV=development && grunt
or
$ export NODE_ENV=staging && grunt
You will also see either of the following messages logged to the console:
>> Copying icons from "dev"...
or
>> Copying icons from "staging"...
After process.env.NODE_ENV has been set to either development or staging then just running $ grunt via your CLI, will copy files according to which environment is set.

Cannot put winston inside a nodejs module

I'm separating my application in modules, but each of these modules have functions that must me logged. So my idea was to create a file winstonConfig.js which would configure the winston, and then I'd require this file in each of the modules that need to log things. Here's winstonConfig.js:
var winston = require('winston');
winston.add(winston.transports.Riak, { level: 'warn' });
winston.add(winston.transports.File, { filename: 'mylogfile.log', level: 'silly' });
exports.log = winston.log;
exports.debug = winston.debug;
exports.error = winston.error;
(btw, is there a way to export everything once?)
but when I require('./winstonConfig.js') in my index.js, I get:
node_modules/winston/lib/winston/logger.js:481
var instance = created ? transport : (new (transport)(options));
^
TypeError: transport is not a constructor
but the exact same code (without exports) will work without any problem when put in index.js (the problem is that then I cannot import this to other modules)
I got the same error with a new project, but when I was trying to use "logger.transports.DailyRotateFile". Then I realized that my code (that was copied from another project) just works for winston 1 (same version used on the other project). So, I just downgraded the lib to version 1 and everything worked normally:
$ npm uninstall winston --save
$ npm install winston#1.x.x --save
But if you want to use winston 2, I found the solution below to use DailyRotateFile - and, probably, there is a similar solution to use other kind of transports.
var winston = require('winston'), expressWinston = require('express-winston');
winston.transports.DailyRotateFile = require('winston-daily-rotate-file');
It looks like you're missing:
require('winston-riak');
I get the same error with your code.
If I comment out the addition of the Riak transport I get no error.
If I require winston-riak:
var winston = require('winston');
require('winston-riak');
winston.add(winston.transports.Riak, { level: 'warn' });
winston.add(winston.transports.File, { filename: 'mylogfile.log', level: 'debug' });
exports.log = winston.log;
exports.debug = winston.debug;
exports.error = winston.error;
I get error: TypeError: riakjs.getClient is not a function. This appears to be because 'winston-riak' tries to execute riakjs.getClient(options) but, per https://github.com/mostlyserious/riak-js/issues/234, getClient is the exported function, rather than a method of the exported object. The winston-riak module hasn't been updated for 5 years. It seems it is not compatible with the current riak-js, which was updated 2 years ago.

How to exec in NodeJS using the user's environment?

I am trying to execute a command in Node:
cd "/www/foo/" && "/path/to/git/bin/git.exe" config --list --global
Basically, I want to execute a Git command that returns global configuration (for the current user).
This works fine for me when I execute the command directly on cli. It also works if I do it like this in Node:
var exec = require('child_process').exec;
var config = {
maxBuffer: 10000 * 1024
};
exec('cd "/www/foo/" && "/path/to/git/bin/git.exe" config --list --global', config, function() {
console.log(arguments);
});
However, as soon as I specify the environment to the config:
var exec = require('child_process').exec;
var config = {
maxBuffer: 10000 * 1024,
env: { // <--- this one
}
};
exec('cd "/www/foo/" && "/path/to/git/bin/git.exe" config --list --global', config, function() {
console.log(arguments);
});
Things break:
Command failed: fatal: unable to read config file
'(null)/(null)/.gitconfig': No such file or directory
I know the reason, it is because the executed Git program is no longer executed under the user environment (like it is in cli), and can't retrieve the user directory to read global configuration (in Git, global config = user config) and I believe /(null)/(null)/.gitconfig should be /Users/MyName/.gitconfig which does exist.
My question is, how can I specify the current user environment while still being able to specify my own additional environment properties?
I solved it.
I retrieved the current environment from process.env and extended it with my own properties:
var environment = process.env;
environment.customProp = 'foo';
var config = {
maxBuffer: 10000 * 1024,
env: environment
};
So the problem was I missed the entire environment when I overwrote it.

Categories