diff --git a/DESCRIPTION b/DESCRIPTION index c99e8f1..c8e536a 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -28,7 +28,8 @@ Imports: glue, stringr, zip, - here + here, + fs Config/roxygen2/version: 8.0.0 Suggests: testthat (>= 3.0.0) diff --git a/NAMESPACE b/NAMESPACE index 629f644..e20ce00 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -4,9 +4,13 @@ export(arrangeCdmNames) export(assertCdmNames) export(createResultsDir) export(getPkgZips) +export(setLoggers) export(unZipStudyFiles) export(zipStudyFiles) -importFrom(ParallelLogger,logInfo) +importFrom(ParallelLogger,createFileAppender) +importFrom(ParallelLogger,createLogger) +importFrom(ParallelLogger,layoutParallel) +importFrom(ParallelLogger,registerLogger) importFrom(checkmate,assertCharacter) importFrom(checkmate,assertDirectoryExists) importFrom(checkmate,assertFileExists) @@ -16,6 +20,7 @@ importFrom(cli,cli_alert_danger) importFrom(cli,cli_alert_info) importFrom(cli,cli_alert_success) importFrom(cli,cli_alert_warning) +importFrom(fs,path_ext_set) importFrom(glue,glue) importFrom(glue,glue_collapse) importFrom(here,here) diff --git a/R/createResultsDir.R b/R/createResultsDir.R index 3c3c3eb..6e86872 100644 --- a/R/createResultsDir.R +++ b/R/createResultsDir.R @@ -17,42 +17,65 @@ #' \item \code{resultsDirName}: The name of the results subdirectory. #' } #' -#' @importFrom ParallelLogger logInfo +#' @importFrom cli cli_alert_info #' @importFrom checkmate assertDirectoryExists #' @importFrom glue glue #' #' @export +#' +#' @examples +#' outputDir <- file.path( +#' tempdir(), +#' "examples" +#' ) +#' directories <- createResultsDir( +#' outputDir, +#' dbname = "OMOP" +#' ) +#' unlink(outputDir, recursive = TRUE) createResultsDir <- function( outputDir = NULL, dbname ) { # Set folder location for results ---- - ParallelLogger::logInfo("Setting location for results") + cli::cli_alert_info( + "Creating locations to save results" + ) if (is.null(outputDir)) { outputDir <- getwd() - checkmate::assertDirectoryExists(outputDir) + checkmate::assertDirectoryExists( + outputDir + ) } else { if (!dir.exists(outputDir)) { - dir.create(outputDir) - checkmate::assertDirectoryExists(outputDir) + dir.create( + outputDir + ) + checkmate::assertDirectoryExists( + outputDir + ) } else { - outputDir <- normalizePath(outputDir) - checkmate::assertDirectoryExists(outputDir) + outputDir <- normalizePath( + outputDir + ) + checkmate::assertDirectoryExists( + outputDir + ) } } - - resultsDirName <- glue::glue("results_{dbname}") - + resultsDirName <- glue::glue( + "results_{dbname}" + ) resultsDir <- file.path( outputDir, resultsDirName ) - if (!dir.exists(resultsDir)) { dir.create(resultsDir) } - - checkmate::assertDirectoryExists(resultsDir) + checkmate::assertDirectoryExists( + resultsDir + ) return( list( outputDir = outputDir, diff --git a/R/getPkgZips.R b/R/getPkgZips.R index 6033362..e0ebe2c 100644 --- a/R/getPkgZips.R +++ b/R/getPkgZips.R @@ -13,15 +13,14 @@ #' @export #' #' @examples +#' \dontrun{ #' pkg_status_list <- getPkgZips() -#' #' # Format supp in this way: #' devtools <- list(Package = "devtools", Version = "2.5.1") #' duckdb <- list(Package = "duckdb", Version = "1.5.2") #' supp <- list(Packages = list(devtools = devtools, duckdb = duckdb)) -#' #' pkg_status_list <- getPkgZips(supplement = supp) -#' +#' } #' @details #' If the package version is not found under any of the R minor releases, the package will be downloaded from the specified `backupRrel` regardless of package version specified in renv.lock #' @importFrom renv lockfile_read diff --git a/R/setLoggers.R b/R/setLoggers.R new file mode 100644 index 0000000..832927b --- /dev/null +++ b/R/setLoggers.R @@ -0,0 +1,115 @@ +#' `setLoggers()` as text files in the results directory +#' +#' @description +#' Sets `ohdsi/ParallelLogger` log and error report for a study. Logger +#' registered as 'OMOP_STUDY_LOGGER' and error report as 'OMOP_STUDY_ERROR_REPORT'. +#' Please note: avoid using inside a tryCatch() or similar because events +#' will not be 'obsorbed' and not recorded by ParallelLogger. +#' +#' @param resultsDir A valid folder where to save the results of a study. +#' This function will work best with the folder structure formed by +#' `createsResultsDir()` +#' @param logFileName A file name in character. Default 'log' +#' @param errorFileName A file name in character. Default 'error' +#' @param eventLevel TRACE is the default, captures all the output from +#' the console +#' @param errorLevel ERROR is the default, captures errors and fatal events +#' +#' @returns Invisible +#' +#' @importFrom checkmate assertDirectoryExists +#' @importFrom checkmate assertCharacter +#' @importFrom fs path_ext_set +#' @importFrom ParallelLogger registerLogger createLogger createFileAppender layoutParallel +#' @importFrom cli cli_alert_info +#' @importFrom glue glue +#' +#' @export +#' +#' @examples +#' outputDir <- file.path( +#' tempdir(), +#' "examples" +#' ) +#' directories <- createResultsDir( +#' outputDir, +#' dbname = "OMOP" +#' ) +#' setLoggers( +#' resultsDir = directories$resultsDir +#' ) +#' ParallelLogger::clearLoggers() +#' unlink(outputDir, recursive = TRUE) +setLoggers <- function( + resultsDir, + logFileName = "log", + errorFileName = "error", + eventLevel = "TRACE", + errorLevel = "ERROR" +) { + + checkmate::assertDirectoryExists(resultsDir) + checkmate::assertCharacter(logFileName) + checkmate::assertCharacter(errorFileName) + + stopifnot( + 'eventLevel should be one of: + "TRACE", "DEBUG", "INFO", "WARN", + "ERROR", "FATAL"' = eventLevel %in% c( + "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL" + ) + ) + + # Logger ---- + logFileLocation <- file.path( + resultsDir, + fs::path_ext_set( + logFileName, + ".txt" + ) + ) + ParallelLogger::registerLogger( + logger <- ParallelLogger::createLogger( + name = "OMOP_STUDY_LOGGER", + threshold = eventLevel, + appenders = list( + ParallelLogger::createFileAppender( + layout = ParallelLogger::layoutParallel, + fileName = logFileLocation + ) + ) + ) + ) + ParallelLogger::logInfo( + glue::glue( + "Logger file will be created at: {resultsDir}" + ) + ) + checkmate::assertFileExists(logFileLocation) + + # Error --------------- + errorFileLocation <- file.path( + resultsDir, + fs::path_ext_set( + errorFileName, + ".txt" + ) + ) + + ParallelLogger::registerLogger( + ParallelLogger::createLogger( + name = "OMOP_STUDY_ERROR_REPORT", + threshold = errorLevel, + appenders = list( + ParallelLogger::createFileAppender( + layout = ParallelLogger::layoutErrorReport, + fileName = errorFileLocation, + overwrite = TRUE, + expirationTime = 60 + ) + ) + ) + ) + + return(invisible()) +} diff --git a/R/unzipStudyFiles.R b/R/unzipStudyFiles.R index 1da5225..8fbc2aa 100644 --- a/R/unzipStudyFiles.R +++ b/R/unzipStudyFiles.R @@ -15,6 +15,23 @@ #' @importFrom glue glue #' #' @export +#' +#' @examples +#' \dontrun{ +#' path <- testthat::test_path( +#' "data", +#' "results_execution" +#' ) +#' outputDir <- file.path( +#' tempdir(), +#' "examples" +#' ) +#' unZipStudyFiles( +#' path = path, +#' outputDir = outputDir +#' ) +#' unlink(outputDir, recursive = TRUE) +#' } unZipStudyFiles <- function( path, pattern, diff --git a/R/zipStudyFiles.R b/R/zipStudyFiles.R index 84ddeb3..4de4547 100644 --- a/R/zipStudyFiles.R +++ b/R/zipStudyFiles.R @@ -12,6 +12,22 @@ #' @importFrom glue glue #' #' @export +#' @examples +#' outputDir <- file.path( +#' tempdir(), +#' "examples" +#' ) +#' dbname <- "IPCI" +#' directories <- createResultsDir( +#' outputDir, +#' dbname = dbname +#' ) +#' zipStudyFiles( +#' resultsDirName = directories$resultsDir, +#' outputDir = directories$outputDir, +#' dbname = dbname +#' ) +#' unlink(outputDir, recursive = TRUE) zipStudyFiles <- function( resultsDirName, outputDir, diff --git a/man/createResultsDir.Rd b/man/createResultsDir.Rd index 401224a..8083910 100644 --- a/man/createResultsDir.Rd +++ b/man/createResultsDir.Rd @@ -26,3 +26,14 @@ Creates a subdirectory for results based on the database name within a specified output directory. If the output directory is not provided, the current working directory is used. } +\examples{ +outputDir <- file.path( + tempdir(), + "examples" +) +directories <- createResultsDir( + outputDir, + dbname = "OMOP" + ) +unlink(outputDir, recursive = TRUE) +} diff --git a/man/getPkgZips.Rd b/man/getPkgZips.Rd index 2ba988e..081ac12 100644 --- a/man/getPkgZips.Rd +++ b/man/getPkgZips.Rd @@ -36,13 +36,12 @@ A function that locates and downloads Windows binaries (.zip) from CRAN based on If the package version is not found under any of the R minor releases, the package will be downloaded from the specified `backupRrel` regardless of package version specified in renv.lock } \examples{ +\dontrun{ pkg_status_list <- getPkgZips() - # Format supp in this way: devtools <- list(Package = "devtools", Version = "2.5.1") duckdb <- list(Package = "duckdb", Version = "1.5.2") supp <- list(Packages = list(devtools = devtools, duckdb = duckdb)) - pkg_status_list <- getPkgZips(supplement = supp) - +} } diff --git a/man/setLoggers.Rd b/man/setLoggers.Rd new file mode 100644 index 0000000..62eb72a --- /dev/null +++ b/man/setLoggers.Rd @@ -0,0 +1,52 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/setLoggers.R +\name{setLoggers} +\alias{setLoggers} +\title{`setLoggers()` as text files in the results directory} +\usage{ +setLoggers( + resultsDir, + logFileName = "log", + errorFileName = "error", + eventLevel = "TRACE", + errorLevel = "ERROR" +) +} +\arguments{ +\item{resultsDir}{A valid folder where to save the results of a study. +This function will work best with the folder structure formed by +`createsResultsDir()`} + +\item{logFileName}{A file name in character. Default 'log'} + +\item{errorFileName}{A file name in character. Default 'error'} + +\item{eventLevel}{TRACE is the default, captures all the output from +the console} + +\item{errorLevel}{ERROR is the default, captures errors and fatal events} +} +\value{ +Invisible +} +\description{ +Sets `ohdsi/ParallelLogger` log and error report for a study. Logger +registered as 'OMOP_STUDY_LOGGER' and error report as 'OMOP_STUDY_ERROR_REPORT'. +Please note: avoid using inside a tryCatch() or similar because events +will not be 'obsorbed' and not recorded by ParallelLogger. +} +\examples{ +outputDir <- file.path( + tempdir(), + "examples" +) +directories <- createResultsDir( + outputDir, + dbname = "OMOP" + ) +setLoggers( + resultsDir = directories$resultsDir + ) +ParallelLogger::clearLoggers() +unlink(outputDir, recursive = TRUE) +} diff --git a/man/unZipStudyFiles.Rd b/man/unZipStudyFiles.Rd index ea01921..2e637fa 100644 --- a/man/unZipStudyFiles.Rd +++ b/man/unZipStudyFiles.Rd @@ -23,3 +23,20 @@ A message stating the location of the uncompressed results \description{ `unZipStudyFiles()` uncompress study results } +\examples{ + \dontrun{ +path <- testthat::test_path( + "data", + "results_execution" +) +outputDir <- file.path( + tempdir(), + "examples" +) +unZipStudyFiles( + path = path, + outputDir = outputDir +) +unlink(outputDir, recursive = TRUE) +} +} diff --git a/man/zipStudyFiles.Rd b/man/zipStudyFiles.Rd index eb03143..3bd8223 100644 --- a/man/zipStudyFiles.Rd +++ b/man/zipStudyFiles.Rd @@ -19,3 +19,20 @@ A message stating the location of the compressed results \description{ `zipStudyFiles()` compress study results } +\examples{ +outputDir <- file.path( + tempdir(), + "examples" + ) +dbname <- "IPCI" +directories <- createResultsDir( + outputDir, + dbname = dbname +) +zipStudyFiles( + resultsDirName = directories$resultsDir, + outputDir = directories$outputDir, + dbname = dbname +) +unlink(outputDir, recursive = TRUE) +} diff --git a/renv.lock b/renv.lock index 8badab4..d075dfe 100644 --- a/renv.lock +++ b/renv.lock @@ -90,6 +90,17 @@ ], "Hash": "2e004ed19964915a8faf48a574439be9" }, + "fs": { + "Package": "fs", + "Version": "2.1.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "methods" + ], + "Hash": "09278623bca442bc53b0940ffa2f6d87" + }, "glue": { "Package": "glue", "Version": "1.8.1", @@ -101,6 +112,16 @@ ], "Hash": "f8122473e9a49e00d0642f78235ca5e3" }, + "here": { + "Package": "here", + "Version": "1.0.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "rprojroot" + ], + "Hash": "e5114f2abe04168238181913a8572358" + }, "httr": { "Package": "httr", "Version": "1.4.8", @@ -201,6 +222,16 @@ ], "Hash": "f88151fb9ca15e72dc351deb1328716e" }, + "rprojroot": { + "Package": "rprojroot", + "Version": "2.1.1", + "Source": "Repository", + "Repository": "https://cloud.r-project.org", + "Requirements": [ + "R" + ], + "Hash": "b2453de2d29aa646afe4781defdc7903" + }, "rstudioapi": { "Package": "rstudioapi", "Version": "0.18.0", diff --git a/tests/testthat/test-setLoggers.R b/tests/testthat/test-setLoggers.R new file mode 100644 index 0000000..9ea0a3a --- /dev/null +++ b/tests/testthat/test-setLoggers.R @@ -0,0 +1,38 @@ +test_that("Create logger files correctly", { + outputDir <- file.path( + tempdir() + ) + + dirs <- createResultsDir( + outputDir = outputDir, + dbname = "LOGGER" + ) + + studyGenerics::setLoggers( + resultsDir = dirs$resultsDir + ) + + ParallelLogger::logError("Test error.txt") + ParallelLogger::clearLoggers() + + file.path( + outputDir, + "results_LOGGER", + "log.txt" + ) |> + file.exists() |> + expect_true() + + file.path( + outputDir, + "results_LOGGER", + "error.txt" + ) |> + file.exists() |> + expect_true() + + unlink( + outputDir, + recursive = TRUE + ) +})