5

I am trying to capture complete console log of my R script. I want a chronological order of everything, warnings printed as they occur. I tried this:

options(warn = 1)

tmpSinkfileName <- tempfile()
sink(tmpSinkfileName, split = TRUE)

cat("Doing something\n")
warning("Hi here")
cat("Doing something else\n")
warning("Hi there")

sink()
console.out <- readChar(tmpSinkfileName, file.info(tmpSinkfileName)$size)
unlink(tmpSinkfileName)

cat(console.out)
# Doing something
# Doing something else
warnings()
# NULL

but unfortunatelly the warnings are missing in console.out. How can I do this? According to the docs, options(warn = 1) should print the warnings as they occur. Unfortunatelly, they were not captured by sink().

Tomas
  • 57,621
  • 49
  • 238
  • 373
  • `R CMD BATCH script.R` produces a file script.Rout with the complete session; maybe that's consistent with your use case? (`R CMD BATCH --vanilla --silent` to avoid accidentally loading saved work spaces and avoiding the splash screen). – Martin Morgan Sep 20 '14 at 12:55

2 Answers2

6

Almost got it, but it's pretty complicated and it's pretty annoying that unlike the standard output, the message output cannot be split, i.e. redirected to the file and kept in the output at the same time (UNIX tee behaviour)!

options(warn = 1)

tmpSinkfileName <- tempfile()
tmpFD <- file(tmpSinkfileName, open = "wt")
sink(tmpFD, split = TRUE)
sink(tmpFD, type = "message") 

cat("Doing something\n")
warning("Hi here")
cat("Doing something else\n")
warning("Hi there")

sink(type = "message") 
sink()
console.out <- readChar(tmpSinkfileName, file.info(tmpSinkfileName)$size)
unlink(tmpSinkfileName)

cat(console.out)

If I try

sink(tmpFD, type = "message", split = TRUE) 

it says

Error in sink(tmpFD, type = "message", split = TRUE) : cannot split the message connection

which is pretty annoying!

Tomas
  • 57,621
  • 49
  • 238
  • 373
4

I wrote the following function to capture ouput and messages:

create_log <- function(logfile_name, path) {
  if (file.exists(paste0(path, logfile_name))) {
    file.remove(paste0(path, logfile_name))
  }
  fid <- file(paste0(path, logfile_name), open = "wt")
  sink(fid, type = "message", split = F)
  sink(fid, append = T, type = "output", split = T)
  warning("Use closeAllConnections() in the end of the script")
}
Christoph
  • 6,841
  • 4
  • 37
  • 89
  • this is the same I got in my answer, and it still has the drawbacks, i.e. not spliting the warnings and errors to the standard output. – Tomas Jun 07 '19 at 05:33