checkout supervisord which is a logging and babysitting tool which becomes the parent of processes like a node server which can handle redirecting both standard out and standard error to files of your choosing ... besides it will sniff for abends and throw the child process back in when needed
here is a typical config file : /etc/supervisor/conf.d/supervisord.conf
[supervisord]
nodaemon=true
logfile=GKE_MASTER_LOGDIR/supervisord_nodejs_GKE_FLAVOR_USER.log
pidfile=GKE_MASTER_LOGDIR/supervisord_nodejs_GKE_FLAVOR_USER.pid
stdout_logfile_maxbytes = 1MB
stderr_logfile_maxbytes = 1MB
logfile_backups = 50
# loglevel = debug
[program:nodejs]
command=/tmp/boot_nodejs.sh %(ENV_MONGO_SERVICE_HOST)s %(ENV_MONGO_SERVICE_PORT)s
stdout_logfile = GKE_MASTER_LOGDIR/nodejs_GKE_FLAVOR_USER_stdout.log
stderr_logfile = GKE_MASTER_LOGDIR/nodejs_GKE_FLAVOR_USER_stderr.log
stdout_logfile_maxbytes = 1MB
stderr_logfile_maxbytes = 1MB
logfile_backups = 50
autostart = True
autorestart = True
# user = GKE_NON_ROOT_USER
in my case this all happens inside a Docker container so here is a snippet of my Dockerfile which launches supervisord which in turn launches nodejs and in so doing redirects stdout / err to logging files which supervisord rotates based on space and/or time ... use of Docker is orthogonal to using supervisord so YMMV
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf" ]
for completeness below I include the boot_nodejs.sh referenced above
#!/bin/bash
given_mongo_service_host=$1
given_mongo_service_port=$2
current_dir=$(dirname "${BASH_SOURCE}")
current_timestamp="timestamp "$(date '+%Y%m%d_%H%M%S_%Z')
echo
echo "______________ fresh nodejs server bounce ______________ $current_timestamp"
echo
# ............... now output same to standard error so its log gets the hat tip
(>&2 echo )
(>&2 echo "______________ fresh nodejs server bounce ______________ $current_timestamp" )
(>&2 echo )
# ................
export MONGO_URL=mongodb://$given_mongo_service_host:$given_mongo_service_port
type node
node main.js