Skip to content

Commit

Permalink
Merge pull request #165 from ljwoodley/monitor_job_runs
Browse files Browse the repository at this point in the history
Monitor failed job runs
  • Loading branch information
pbchase authored Oct 16, 2024
2 parents a6b29e2 + 1ec989d commit 71bb032
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 3 deletions.
4 changes: 2 additions & 2 deletions R/logging.R
Original file line number Diff line number Diff line change
Expand Up @@ -641,7 +641,7 @@ write_info_log_entry <- function(conn, target_db_name, table_written = NULL, df,
#' @param email_from The email addresses of the sender
#' @param df_to_email (Optional) A dataframe or a list of dataframes to be included as file attachment(s). If this parameter is used, `file_name` must also be specified.
#' Each dataframe in the list must have a corresponding file name in the `file_name` parameter to ensure a one-to-one match between dataframes and file names.
#' @param file_name (Optional) A character vector specifying the file name(s) of the attachment(s). Valid file extensions are `.csv`, `.xlsx`, and `.zip`. Each file name must be unique.
#' @param file_name (Optional) A character vector specifying the file name(s) of the attachment(s). Valid file extensions are `.csv`, `.xlsx`, `.zip` and, `.txt`. Each file name must be unique.
#' @param ... Additional arguments passed directly to the file writing functions: `write.csv` for CSV files, and `writexl::write_xlsx` for XLSX files.
#'
#' @return No returned value. It performs an action by sending an email.
Expand Down Expand Up @@ -783,7 +783,7 @@ send_email <-
}
}

if (file_extension == "zip" &&
if ((file_extension == "zip" || file_extension == "txt") &&
!file.copy(file_name[[i]], output_dir, overwrite = TRUE)) {
stop(paste("Failed to move", file_name[[i]]))
}
Expand Down
47 changes: 47 additions & 0 deletions etl/run_etl.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
library(redcapcustodian)
library(dotenv)
library(callr)
library(argparse)

set_script_run_time()

parser <- ArgumentParser()
parser$add_argument("script_name", help="Script to be run")
parser$add_argument("optional_args", nargs='*', help="Zero or more optional arguments of any type")

if (!interactive()) {
args <- parser$parse_args()
} else {
args <- parser$parse_args(
c(
"study_template/etl/test_failure_alert.R",
"test",
"another test"
)
)
}

script_name <- args$script_name
optional_args <- args$optional_args

if(!fs::file_exists(script_name)) {
stop(sprintf("Specified file, %s, does not exist", script_name))
}

tryCatch({
if (length(optional_args) == 0) {
rscript(script = script_name, stderr = "log.txt")
} else {
rscript(script = script_name, cmdargs = optional_args, stderr = "log.txt")
}
}, error = function(e) {
email_body <- "See the attached log for error details."
script_path <- paste(basename(getwd()), script_name, sep = "/")
email_subject <- paste0("Failed | ", script_path, " | ", format(get_script_run_time(), "%Y-%m-%d"))
file_name = "log.txt"

send_email(email_body = email_body, email_subject = email_subject, file_name = file_name)
})



11 changes: 11 additions & 0 deletions etl/test_failure_alert.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
print("Hello, example host!")

args <- commandArgs(trailingOnly = TRUE)

# Test that the command line args are read
print(paste0("This is a ", args[1]))
print(paste0("This is ", args[2]))

# This will fail as test.csv does not exist.
read.csv("test.csv")

2 changes: 1 addition & 1 deletion man/send_email.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions study_template/cron/test_failure_alert
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Test email alert on script failure
0 0 1 * * root /usr/bin/docker run --rm --env-file /rcc/study_template/.env rcc.site Rscript etl/run_etl.R etl/test_failure_alert.R test "another test"

47 changes: 47 additions & 0 deletions study_template/etl/run_etl.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
library(redcapcustodian)
library(dotenv)
library(callr)
library(argparse)

set_script_run_time()

parser <- ArgumentParser()
parser$add_argument("script_name", help="Script to be run")
parser$add_argument("optional_args", nargs='*', help="Zero or more optional arguments of any type")

if (!interactive()) {
args <- parser$parse_args()
} else {
args <- parser$parse_args(
c(
"study_template/etl/test_failure_alert.R",
"test",
"another test"
)
)
}

script_name <- args$script_name
optional_args <- args$optional_args

if(!fs::file_exists(script_name)) {
stop(sprintf("Specified file, %s, does not exist", script_name))
}

tryCatch({
if (length(optional_args) == 0) {
rscript(script = script_name, stderr = "log.txt")
} else {
rscript(script = script_name, cmdargs = optional_args, stderr = "log.txt")
}
}, error = function(e) {
email_body <- "See the attached log for error details."
script_path <- paste(basename(getwd()), script_name, sep = "/")
email_subject <- paste0("Failed | ", script_path, " | ", format(get_script_run_time(), "%Y-%m-%d"))
file_name = "log.txt"

send_email(email_body = email_body, email_subject = email_subject, file_name = file_name)
})



11 changes: 11 additions & 0 deletions study_template/etl/test_failure_alert.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
print("Hello, example host!")

args <- commandArgs(trailingOnly = TRUE)

# Test that the command line args are read
print(paste0("This is a ", args[1]))
print(paste0("This is ", args[2]))

# This will fail as test.csv does not exist.
read.csv("test.csv")

0 comments on commit 71bb032

Please sign in to comment.