diff --git a/DESCRIPTION b/DESCRIPTION index ade5e74..3930653 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -45,6 +45,7 @@ Imports: shiny, heatmaply, shinyBS, shinythemes, - shinycssloaders + shinycssloaders, + log4r RoxygenNote: 6.0.1 biocViews: diff --git a/NAMESPACE b/NAMESPACE index 4da3252..dac65a7 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -32,6 +32,7 @@ export(pca) export(pcaUI) export(scatterPlot) export(scatterPlotUI) +export(set_logger) export(transformation) export(transformationUI) import(data.table) diff --git a/R/and.R b/R/and.R index 22f9b31..fc1afd0 100644 --- a/R/and.R +++ b/R/and.R @@ -254,6 +254,8 @@ and <- function(input, output, session, data, show.elements = NULL, element.grou on.exit(progress$close()) progress$set(0, message = "Apply Filter") + log_message(message = "Applying filter...", level = "INFO", token = session$token) + or.modules <- modules() step <- 0.9 / length(or.modules) @@ -280,6 +282,8 @@ and <- function(input, output, session, data, show.elements = NULL, element.grou progress$set(1) + log_message(message = "Done.", level = "INFO", token = session$token) + return(list(bool = and.selection.bool, text = unlist(or.selection.text))) }) diff --git a/R/featureSelector.R b/R/featureSelector.R index 3f1a6bb..2be9965 100644 --- a/R/featureSelector.R +++ b/R/featureSelector.R @@ -143,6 +143,8 @@ featureSelector <- function(input, output, session, data, features = NULL, featu # reset row_selector shiny::observeEvent(input$reset, { + log_message(message = "Filter reset", level = "INFO", token = session$token) + value(NULL) row_selector <<- shiny::callModule(orNumeric, "row_selector", choices = choices, value = value_wrapper, label = "Select n features from the top and/or bottom of the list", stepsize = 1) }) @@ -238,6 +240,8 @@ featureSelector <- function(input, output, session, data, features = NULL, featu # first filter (and) whole set in table select <- shiny::eventReactive(eventExpr = input$select, { + log_message(message = "Filtering data", level = "INFO", token = session$token) + data <- data.r()[and_selected()$bool] }) diff --git a/R/geneView.R b/R/geneView.R index bfb8298..55f64c0 100644 --- a/R/geneView.R +++ b/R/geneView.R @@ -166,6 +166,8 @@ geneView <- function(input, output, session, data, metadata, level = NULL, plot. # reset shiny::observeEvent(input$reset, { + log_message("GeneView: reset", "INFO", token = session$token) + shinyjs::reset("genes") shinyjs::reset("plotType") shinyjs::reset("groupby") @@ -261,6 +263,8 @@ geneView <- function(input, output, session, data, metadata, level = NULL, plot. shinyjs::disable("download") plot <- shiny::eventReactive(input$plot, { + log_message("GeneView: computing plot...", "INFO", token = session$token) + # enable downloadButton shinyjs::enable("download") clearPlot(FALSE) @@ -295,6 +299,7 @@ geneView <- function(input, output, session, data, metadata, level = NULL, plot. scale = size()$scale ) + log_message("GeneView: done.", "INFO", token = session$token) progress$set(1, detail = "Return plot") return(plot) }) @@ -340,6 +345,8 @@ geneView <- function(input, output, session, data, metadata, level = NULL, plot. if(clearPlot()) { return() } else { + log_message("GeneView: render plot interactive", "INFO", token = session$token) + #progress indicator progress <- shiny::Progress$new() on.exit(progress$close()) @@ -359,6 +366,8 @@ geneView <- function(input, output, session, data, metadata, level = NULL, plot. if(clearPlot()) { return() } else { + log_message("GeneView: render plot static", "INFO", token = session$token) + #progress indicator progress <- shiny::Progress$new() on.exit(progress$close()) @@ -374,6 +383,8 @@ geneView <- function(input, output, session, data, metadata, level = NULL, plot. output$download <- shiny::downloadHandler(filename = "geneView.zip", content = function(file) { + log_message("GeneView: download", "INFO", token = session$token) + download(file = file, filename = "geneView.zip", plot = plot()$plot, width = plot()$width, height = plot()$height, ppi = plot()$ppi, ui = user_input()) }) diff --git a/R/global.R b/R/global.R new file mode 100644 index 0000000..3845d2f --- /dev/null +++ b/R/global.R @@ -0,0 +1,37 @@ + +wilson.globals <- new.env(parent = emptyenv()) + +#' set a log4r logger used within the package +#' +#' @param logger A logger object see \code{\link[log4r]{create.logger}}. NULL to disable logging. +#' @param token Set a unique identifier for this logger. +#' +#' @details This function will save each logger in the wilson.globals environment. Each logger is stored by the name 'logger'[token] (e.g. 'logger6b821824b0b53b1a3e8f531a34d0d6e6'). +#' @details Use onSessionEnded to clean up after logging. See \code{\link[shiny]{onFlush}}. +#' +#' @export +set_logger <- function(logger, token = NULL) { + if(is.null(logger) || is(logger, "logger")) { + assign(x = paste0("logger", token), value = logger, envir = wilson.globals) + } +} + +#' logger message convenience function +#' +#' @param message String of message to be written in log. See \code{\link[log4r]{levellog}}. +#' @param level Set priority level of the message (number or character). See \code{\link[log4r]{levellog}}. +#' @param token Use token bound to this identifier. +#' +log_message <- function(message, level = c("DEBUG", "INFO", "WARN", "ERROR", "FATAL"), token = NULL) { + logger <- get(paste0("logger", token), envir = wilson.globals) + + if(!is.null(logger)) { + switch(level, + DEBUG = log4r::debug(logger, message), + INFO = log4r::info(logger, message), + WARN = log4r::warn(logger, message), + ERROR = log4r::error(logger, message), + FATAL = log4r::fatal(logger, message) + ) + } +} diff --git a/R/global_cor_heatmap.R b/R/global_cor_heatmap.R index f1c2baa..db472ed 100644 --- a/R/global_cor_heatmap.R +++ b/R/global_cor_heatmap.R @@ -225,6 +225,8 @@ global_cor_heatmap <- function(input, output, session, data, types, plot.method # reset ui shiny::observeEvent(input$reset, { + log_message("Global correlation heatmap: reset", "INFO", token = session$token) + shinyjs::reset("calc") shinyjs::reset("calc_method") shinyjs::reset("distance") @@ -313,6 +315,8 @@ global_cor_heatmap <- function(input, output, session, data, types, plot.method # build plot object plot <- shiny::eventReactive(input$plot, { + log_message("Global correlation heatmap: computing plot...", "INFO", token = session$token) + # enable downloadButton shinyjs::enable("download") # show plot @@ -362,6 +366,7 @@ global_cor_heatmap <- function(input, output, session, data, types, plot.method # update progress indicator progress$set(1) + log_message("Global correlation heatmap: done.", "INFO", token = session$token) return(plot) }) @@ -374,6 +379,8 @@ global_cor_heatmap <- function(input, output, session, data, types, plot.method if(clearPlot()) { return() } else { + log_message("Global correlation heatmap: render plot static", "INFO", token = session$token) + # progress indicator progress <- shiny::Progress$new() on.exit(progress$close()) @@ -395,6 +402,8 @@ global_cor_heatmap <- function(input, output, session, data, types, plot.method if(clearPlot()) { return() } else { + log_message("Global correlation heatmap: render plot interactive", "INFO", token = session$token) + # progress indicator progress <- shiny::Progress$new() on.exit(progress$close()) @@ -412,6 +421,8 @@ global_cor_heatmap <- function(input, output, session, data, types, plot.method output$download <- shiny::downloadHandler(filename = "global_correlation_heatmap.zip", content = function(file) { + log_message("Global correlation heatmap: download", "INFO", token = session$token) + download(file = file, filename = "global_correlation_heatmap.zip", plot = plot()$plot, width = plot()$width, height = plot()$height, ppi = plot()$ppi, ui = user_input()) }) diff --git a/R/heatmap.R b/R/heatmap.R index 17ac622..b4ce0b2 100644 --- a/R/heatmap.R +++ b/R/heatmap.R @@ -213,6 +213,8 @@ heatmap <- function(input, output, session, data, types, plot.method = "static", # reset ui shiny::observeEvent(input$reset, { + log_message("Heatmap: reset", "INFO", token = session$token) + shinyjs::reset("cluster.distance") shinyjs::reset("cluster.method") shinyjs::reset("clustering") @@ -254,6 +256,8 @@ heatmap <- function(input, output, session, data, types, plot.method = "static", shinyjs::disable("download") plot <- shiny::eventReactive(input$plot, { + log_message("Heatmap: computing plot...", "INFO", token = session$token) + # enable downloadButton shinyjs::enable("download") clearPlot(FALSE) @@ -291,6 +295,7 @@ heatmap <- function(input, output, session, data, types, plot.method = "static", ) progress$set(1) + log_message("Heatmap: done.", "INFO", token = session$token) return(plot) }) @@ -304,6 +309,8 @@ heatmap <- function(input, output, session, data, types, plot.method = "static", if(clearPlot()) { return() } else { + log_message("Heatmap: render plot interactive", "INFO", token = session$token) + #new progress indicator progress <- shiny::Progress$new() on.exit(progress$close()) @@ -328,6 +335,8 @@ heatmap <- function(input, output, session, data, types, plot.method = "static", if(clearPlot()) { return() } else { + log_message("Heatmap: render plot static", "INFO", token = session$token) + #new progress indicator progress <- shiny::Progress$new() on.exit(progress$close()) @@ -343,6 +352,8 @@ heatmap <- function(input, output, session, data, types, plot.method = "static", output$download <- shiny::downloadHandler(filename = "heatmap.zip", content = function(file) { + log_message("Heatmap: download", "INFO", token = session$token) + download(file = file, filename = "heatmap.zip", plot = plot()$plot, width = plot()$width, height = plot()$height, ppi = plot()$ppi, ui = user_input()) }) diff --git a/R/pca.R b/R/pca.R index 53de734..642fb7f 100644 --- a/R/pca.R +++ b/R/pca.R @@ -154,6 +154,8 @@ pca <- function(input, output, session, data, types, levels = NULL, entryLabel = #reset ui shiny::observeEvent(input$reset, { + log_message("PCA: reset", "INFO", token = session$token) + shinyjs::reset("label") shinyjs::reset("dimA") shinyjs::reset("dimB") @@ -235,6 +237,8 @@ pca <- function(input, output, session, data, types, levels = NULL, entryLabel = shinyjs::disable("download") computed.data <- shiny::eventReactive(input$plot, { + log_message("PCA: computing plot...", "INFO", token = session$token) + # enable downloadButton shinyjs::enable("download") clearPlot(FALSE) @@ -262,6 +266,8 @@ pca <- function(input, output, session, data, types, levels = NULL, entryLabel = progress$set(1) + log_message("PCA: done.", "INFO", token = session$token) + # show plot shinyjs::show("pca") @@ -287,6 +293,8 @@ pca <- function(input, output, session, data, types, levels = NULL, entryLabel = if(clearPlot()){ return() } else { + log_message("PCA: render plot", "INFO", token = session$token) + computed.data()$plot } }) @@ -302,6 +310,7 @@ pca <- function(input, output, session, data, types, levels = NULL, entryLabel = output$download <- shiny::downloadHandler(filename = "pca.zip", content = function(file) { + log_message("PCA: download", "INFO", token = session$token) download(file = file, filename = "pca.zip", plot = computed.data()$plot, width = plot_width() / (computed.data()$ppi / 2.54), height = plot_height() / (computed.data()$ppi / 2.54), ppi = computed.data()$ppi, ui = user_input()) }) diff --git a/R/scatterPlot.R b/R/scatterPlot.R index 40056a1..844a51d 100644 --- a/R/scatterPlot.R +++ b/R/scatterPlot.R @@ -188,6 +188,8 @@ scatterPlot <- function(input, output, session, data, types, features = NULL, ma #reset ui shiny::observeEvent(input$reset, { + log_message("Scatterplot: reset", "INFO", token = session$token) + shinyjs::reset("density") shinyjs::reset("line") shinyjs::reset("pointsize") @@ -311,6 +313,8 @@ scatterPlot <- function(input, output, session, data, types, features = NULL, ma shinyjs::disable("download") plot <- shiny::eventReactive(input$plot, { + log_message("Scatterplot: computing plot...", "INFO", token = session$token) + #enable downloadbutton shinyjs::enable("download") clearPlot(FALSE) @@ -358,6 +362,7 @@ scatterPlot <- function(input, output, session, data, types, features = NULL, ma ) progress$set(1) + log_message("Scatterplot: done.", "INFO", token = session$token) return(plot) }) @@ -382,6 +387,8 @@ scatterPlot <- function(input, output, session, data, types, features = NULL, ma if(clearPlot()) { return() } else { + log_message("Scatterplot: render plot static", "INFO", token = session$token) + plot()$plot } } @@ -391,6 +398,8 @@ scatterPlot <- function(input, output, session, data, types, features = NULL, ma if(clearPlot()) { return() } else { + log_message("Scatterplot: render plot interactive", "INFO", token = session$token) + #new progress indicator progress <- shiny::Progress$new() on.exit(progress$close()) @@ -406,6 +415,7 @@ scatterPlot <- function(input, output, session, data, types, features = NULL, ma output$download <- shiny::downloadHandler(filename = "scatterPlot.zip", content = function(file) { + log_message("Scatterplot: download", "INFO", token = session$token) download(file = file, filename = "scatterPlot.zip", plot = plot()$plot, width = plot()$width, height = plot()$height, ppi = plot()$ppi, ui = user_input()) } ) diff --git a/man/log_message.Rd b/man/log_message.Rd new file mode 100644 index 0000000..d94a471 --- /dev/null +++ b/man/log_message.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/global.R +\name{log_message} +\alias{log_message} +\title{logger message convenience function} +\usage{ +log_message(message, level = c("DEBUG", "INFO", "WARN", "ERROR", "FATAL"), + token = NULL) +} +\arguments{ +\item{message}{String of message to be written in log. See \code{\link[log4r]{levellog}}.} + +\item{level}{Set priority level of the message (number or character). See \code{\link[log4r]{levellog}}.} + +\item{token}{Use token bound to this identifier.} +} +\description{ +logger message convenience function +} diff --git a/man/set_logger.Rd b/man/set_logger.Rd new file mode 100644 index 0000000..38ef957 --- /dev/null +++ b/man/set_logger.Rd @@ -0,0 +1,21 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/global.R +\name{set_logger} +\alias{set_logger} +\title{set a log4r logger used within the package} +\usage{ +set_logger(logger, token = NULL) +} +\arguments{ +\item{logger}{A logger object see \code{\link[log4r]{create.logger}}. NULL to disable logging.} + +\item{token}{Set a unique identifier for this logger.} +} +\description{ +set a log4r logger used within the package +} +\details{ +This function will save each logger in the wilson.globals environment. Each logger is stored by the name 'logger'[token] (e.g. 'logger6b821824b0b53b1a3e8f531a34d0d6e6'). + +Use onSessionEnded to clean up after logging. See \code{\link[shiny]{onFlush}}. +}