From 88e1dd199b04c63512bd810b043787126e6bdb1d Mon Sep 17 00:00:00 2001 From: dipterix Date: Fri, 2 Feb 2024 18:46:50 -0500 Subject: [PATCH] allow to print out the debug information --- DESCRIPTION | 2 +- NAMESPACE | 2 + R/report.R | 151 +++++++++++++++++++++++++++++++++++++++++++++ man/debug_info.Rd | 15 +++++ man/export_logs.Rd | 29 +++++++++ 5 files changed, 198 insertions(+), 1 deletion(-) create mode 100644 R/report.R create mode 100644 man/debug_info.Rd create mode 100644 man/export_logs.Rd diff --git a/DESCRIPTION b/DESCRIPTION index 4619b4d..6cc5e72 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: ravemanager Title: Manage 'RAVE' Packages -Version: 1.0.38 +Version: 1.0.39 Authors@R: person("Zhengjia", "Wang", email = "dipterix.wang@gmail.com", role = c("aut", "cre")) diff --git a/NAMESPACE b/NAMESPACE index 9db37b9..8beeecc 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -5,7 +5,9 @@ S3method(print,ravemanager_printable) export(add_shortcuts) export(clear_cache) export(configure_python) +export(debug_info) export(ensure_rpymat) +export(export_logs) export(finalize_installation) export(install) export(ravemanager_version) diff --git a/R/report.R b/R/report.R new file mode 100644 index 0000000..c1d68a9 --- /dev/null +++ b/R/report.R @@ -0,0 +1,151 @@ + +session_log <- function(x = NULL, max_lines = 200, modules = NULL) { + n <- tryCatch({ + as.integer(max_lines) + }, + error = function(e){200L}, + warning = function(e){200L}) + + # x = NULL;max_lines = 200; modules = NULL + ravedash <- asNamespace("ravedash") + dipsaus <- asNamespace("dipsaus") + if(is.function(ravedash$session_log)) { + return(ravedash$session_log(x, max_lines = max_lines, modules = modules)) + } + + if(n <= 0) { n <- 5000L } + if(is.null(x)) { + x <- ravedash$list_session(order = "descend") + if(!length(x)) { + return(structure(character(0L), class = "ravedash_session_log_string", max_lines = n, session_id = NULL)) + } + x <- x[[1]] + } + session <- ravedash$use_session(x) + log_dir <- file.path(session$app_path, "logs") + if(!dir.exists(log_dir)) { + return(structure(character(0L), class = "ravedash_session_log_string", max_lines = n, session_id = session$session_id)) + } + all_modules <- list.files(log_dir, pattern = "\\.log", all.files = FALSE, full.names = FALSE, recursive = FALSE, include.dirs = FALSE) + modules <- all_modules + if(length(modules)) { + modules <- gsub("\\(.log|)$", ".log", x = modules, ignore.case = TRUE) + modules <- c(modules[modules %in% all_modules], "ravedash.log") + } + modules <- unique(modules) + modules <- modules[file.exists(file.path(log_dir, modules))] + if(!length(modules)) { + return(structure(character(0L), class = "ravedash_session_log_string", max_lines = n, session_id = session$session_id)) + } + + logs <- lapply(modules, function(module) { + s <- trimws(readLines(file.path(log_dir, module))) + if(length(s) > n) { + s <- s[ -seq_len(length(s) - n) ] + } + timestamp <- substring(gsub("^(TRACE|DEBUG|INFO|WARN|ERROR|FATAL)[ ]{0, }", "", s), 1, 19) + timestamp <- strptime(timestamp, format = "%Y-%m-%d %H:%M:%S") + nas <- dipsaus$deparse_svec( which(is.na(timestamp)), concatenate = FALSE) + + for(ns_idx in nas) { + idx <- dipsaus$parse_svec(ns_idx) + if(length(idx)) { + midx <- idx[[1]] + if(midx > 1) { + timestamp[ idx ] <- timestamp[[ midx - 1 ]] + } + } + } + data.frame( + time = timestamp, + string = s + ) + }) + logs_combined <- do.call("rbind", logs) + timestamps <- logs_combined$time[!is.na(logs_combined$time)] + + if(length(timestamps) > n) { + tmp <- timestamps[[ order(timestamps, decreasing = TRUE)[[n]] ]] + logs <- lapply(logs, function(log) { + log[log$time >= tmp, ] + }) + logs_combined <- do.call("rbind", logs) + } + return(structure(logs_combined$string[order(logs_combined$time, decreasing = FALSE)], + class = "ravedash_session_log_string", max_lines = n, session_id = session$session_id)) + +} + +#' Print out 'RAVE' session log +#' @param session 'RAVE' session string; default is the most recent (active) +#' session +#' @param modules which module to read; default is all +#' @param max_lines maximum number of lines to read; default is 200 +#' @param verbose whether to print out the log; default is true +#' @returns characters of log +#' @export +export_logs <- function(session = NULL, modules = NULL, + max_lines = Sys.getenv("RAVEMANAGER_BUGREPORT_MAX", "200"), + verbose = TRUE) { + x <- session_log(session, modules = modules, max_lines = max_lines) + x_ <- unclass(x) + session_id <- attr(x_, "session_id") + if(is.null(session_id)) { + session_id <- "empty session ID" + } + if( verbose ) { + tryCatch({ + version_info(vanilla = TRUE) + }, error = function(e) { + cat("Unable to obtain the RAVE version information...\n") + }) + if( !any(grepl("^INFO.*Current session information:[ ]{0,}$", x_ )) ) { + print(utils::sessionInfo()) + } + cat(sprintf(" (%s)\n", session_id)) + cat(x_, sep = "\n") + cat(sprintf("\n", attr(x_, "max_lines"))) + } + return(invisible(x)) +} + +#' Print 'RAVE' debugging information +#' @description +#' This function will generate a report. Please include the report when you +#' file an issue. Useful for reporting issues to 'RAVE' developers. +#' @param max_lines maximum number of log entries to print +#' +#' @export +debug_info <- function(max_lines) { + + has_reprex <- FALSE + + if(!missing(max_lines)) { + Sys.setenv("RAVEMANAGER_BUGREPORT_MAX" = as.character(max_lines[[1]])) + } + + if(!system.file(package = "reprex") != "") { + tryCatch({ + install_packages("reprex") + has_reprex <- TRUE + }, error = function(e){ + }) + } else { + has_reprex <- TRUE + } + if( has_reprex ) { + reprex <- asNamespace("reprex") + reprex$reprex(x = asNamespace("ravemanager")$export_logs(), advertise = FALSE) + + } else { + cat("\014") + message("\014") + message("---- Start: RAVE Debug Info ----------------------------------------") + export_logs() + message("---- End: RAVE Debug Info ------------------------------------------") + } + + message("Please Copy the above debugging information in your issue report :)") + + invisible() +} diff --git a/man/debug_info.Rd b/man/debug_info.Rd new file mode 100644 index 0000000..7c7a646 --- /dev/null +++ b/man/debug_info.Rd @@ -0,0 +1,15 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/report.R +\name{debug_info} +\alias{debug_info} +\title{Print 'RAVE' debugging information} +\usage{ +debug_info(max_lines) +} +\arguments{ +\item{max_lines}{maximum number of log entries to print} +} +\description{ +This function will generate a report. Please include the report when you +file an issue. Useful for reporting issues to 'RAVE' developers. +} diff --git a/man/export_logs.Rd b/man/export_logs.Rd new file mode 100644 index 0000000..9d479c1 --- /dev/null +++ b/man/export_logs.Rd @@ -0,0 +1,29 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/report.R +\name{export_logs} +\alias{export_logs} +\title{Print out 'RAVE' session log} +\usage{ +export_logs( + session = NULL, + modules = NULL, + max_lines = Sys.getenv("RAVEMANAGER_BUGREPORT_MAX", "200"), + verbose = TRUE +) +} +\arguments{ +\item{session}{'RAVE' session string; default is the most recent (active) +session} + +\item{modules}{which module to read; default is all} + +\item{max_lines}{maximum number of lines to read; default is 200} + +\item{verbose}{whether to print out the log; default is true} +} +\value{ +characters of log +} +\description{ +Print out 'RAVE' session log +}