Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get standard output written to a log file when a Shiny app is deployed on the server?

I am having difficulty getting logging info for my Shiny app.

When run on the local machine via runApp() at the R command prompt I have lots of print out to stanard out via cat(), print(), str() etc. I want to see this in a log file when deployed on the server.

We have a fairly default Shiny Server config:

# logs
cd /var/log
l | grep shiny
drwxr-xr-x. 2 shiny  shiny     4096 Nov 20 14:50 shiny-server
-rw-r--r--. 1 shiny  root    181558 Nov 24 16:58 shiny-server.log

cd /var/log/shiny-server
ls -ltr
...
-rw-r-----. 1 shiny shiny  1149 Nov 13 15:19 current-shiny-20151113-151944-49237.log
-rw-r-----. 1 shiny shiny  1031 Nov 20 14:50 current-shiny-20151120-145042-35634.log
-rw-r--r--. 1 shiny root  43690 Nov 24 16:58 access.log

An example of the app log file is

cat current-shiny-20151125-154719-44403.log

Listening on http://127.0.0.1:44403
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.8.3/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.8.3-20140911/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.8.3-20140911/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux
Thread model: posix
gcc version 4.8.3 20140911 (Red Hat 4.8.3-9) (GCC)

This isn't the stuff I write to standard out which I would like to somehow see.

I believe log files are also cleaned up if the process was exited successfully. Can I stop this?

Also where is the app process? It appears the app is run via a SockJSAdapter.R process (see below). And there is just one of these for each URL accessed, even if a URL is simultaneously accessed from several browser windows (say in Firefox and Chrome). In the below 3 different URLs are accessed from 4 browser windows.

ps -alef | egrep "PID|shiny" | grep -v grep
F S UID        PID  PPID  C PRI  NI ADDR SZ WCHAN  STIME TTY          TIME CMD
4 S root     24734     1  0  80   0 - 50506 wait   15:15 ?        00:00:00 /usr/bin/su shiny -c /opt/shiny-server/bin/shiny-server --pidfile=/var/run/shiny-server.pid >> /var/log/shiny-server.log 2>&1
4 S shiny    24736 24734  0  80   0 - 28279 wait   15:15 ?        00:00:00 bash -c /opt/shiny-server/bin/shiny-server --pidfile=/var/run/shiny-server.pid >> /var/log/shiny-server.log 2>&1
0 S shiny    24737 24736  0  80   0 - 245601 ep_pol 15:15 ?       00:00:02 /opt/shiny-server/ext/node/bin/shiny-server /opt/shiny-server/lib/main.js --pidfile=/var/run/shiny-server.pid
0 S shiny    24753 24737  0  80   0 - 91424 ep_pol 15:15 ?        00:00:07 /usr/lib64/R/bin/exec/R --no-save --slave -f /opt/shiny-server/R/SockJSAdapter.R
0 S shiny    25091 24737  1  80   0 - 121894 ep_pol 15:32 ?       00:00:07 /usr/lib64/R/bin/exec/R --no-save --slave -f /opt/shiny-server/R/SockJSAdapter.R
0 S shiny    25188 24737  1  80   0 - 91335 ep_pol 15:39 ?        00:00:03 /usr/lib64/R/bin/exec/R --no-save --slave -f /opt/shiny-server/R/SockJSAdapter.R
like image 603
Desmond Campbell Avatar asked Mar 14 '23 01:03

Desmond Campbell


1 Answers

I had the same problem and solved it as follows:

By default shiny apps deployed on a server will have a logging file in /var/log/shiny-server/. For some reason only stderr is logged - see this discussion. In order to redirect stdout into this file I have a statement in the beginning of the Server.R file:

if (!interactive()) sink(stderr(), type = "output")

This means that locally I do not redirect, as the session is interactive. So basically I redirect stdout into stderr which does not make me happy, but as long as I do not want to manage my own log files it is what I do. Now everything is logged what can typically be seen in the R-REPL while you run the shiny app locally.

like image 87
Sebastian Avatar answered Apr 05 '23 22:04

Sebastian