Writing a logfile from plumber via RStudio Connect

plumber
rstudioconnect

#1

I want to deploy a plumber app via RStudio connect that writes a logfile somewhere where I can access it (via futile.logger). Any hints how to go about that? I am a bit lost.


#2

Once you called a script that was deployed as a plumber API to Connect, the Sandboxing rules apply.

This basically means that your process runs in a protected space and any information you write to the local file system is only available to the process while it is running. In other words, if you were to simply use writeLines(...), you won't be able to access this output outside of Connect.

The solution to this is to write to a destination that you can access outside of Connect. In general, this can be:

  • A database
  • Cloud storage, e.g. AWS S3 storage buckets
  • A cloud service, e.g. Google Sheets
  • A shared folder on the Connect server, i.e. a top level folder you create on the server and have access to
  • Network file share

For example, earlier this week I deployed an API that takes incoming data and records what it did by writing a new line into a Google Sheet. This is quite easy to do, thanks to the googlesheets package.

Here is the real code I deployed to Connect as part of the proof of concept:

library(googlesheets)

if (!file.exists(".httr-oauth")) 
    stop("You must run googledrive::drive_auth() first")
gs <- googlesheets::gs_key("............................................")

record_in_googlesheet <- function(id, title, score){
  newline <- data.frame(timestamp = Sys.time(), id = id, title = title, score = score)
  gs_add_row(gs, input = newline)
}

#* Predicts ticket complexity given the initial issue.
#*
#* @param title Ticket title
#* @param id Ticket id
#* 
#* @post /
function(id, title, description, org) {
  score <- runif(1)
  record_in_googlesheet(id, title, score)
  score
}

Of course, in your case you are writing logs in a the futile.logger file format, so you still have to solve this problem.

Also, you will have to create a folder on the Connect server, e.g. /app-data that you have access to.

The support articles Persistent Storage on RStudio Connect might be helpful, since it describes some of the ways of working with persistent storage in Connect.


#3

Okay thank you, I thought it might be something like this. I have to talk to my admin about accessing some form of persistent storage from RStudio connect then. cheers


#4

This might be crazy... if you have lots of Plumber APIs, you could also think about logging via another RESTful API endpoint :slight_smile: You implement a single logging service (either via Plumber or something else) and log via calls to that logging service.

Alternatively, you could create an R package to encapsulate the sort of thing @andrie is talking about, so that it is easy to add the behavior to any app or API that you are publishing to Connect.

EDIT: One other thought is to implement the logging via a filter endpoint as the plumber docs illustrate. Again, this is only in addition to what @andrie has already mentioned:

#* Log some information about the incoming request
#* @filter logger
function(req){
  cat(as.character(Sys.time()), "-", 
    req$REQUEST_METHOD, req$PATH_INFO, "-", 
    req$HTTP_USER_AGENT, "@", req$REMOTE_ADDR, "\n")
  plumber::forward()
}

#5

thanks for the tips, I will probably see about logging to a database since that will likely be the easiest setup for me in my current situation


#6

Note that with @cole's recommendation those logs are available directly for download in RStudio Connect: