R脚本tryCatch错误日志优化:固定路径、区分脚本、避免覆盖
改进后的RunScript2实现方案
针对你提出的日志问题,以下是基于R基础函数的改进实现,完全满足需求:
核心改进点
- 固定日志存储到主工作路径下的
errors子文件夹 - 错误和警告分别存入
errors.log和warnings.log,采用追加模式避免覆盖 - 每条日志自动关联报错脚本名称和时间戳
- 彻底解决无错误时关闭文件报错的问题
- 无额外包依赖
完整代码
RunScript2 <- function(script_path) { # 创建固定路径的errors目录(主工作路径下) error_dir <- file.path(getwd(), "errors") dir.create(error_dir, showWarnings = FALSE, recursive = TRUE) # 定义错误、警告日志文件路径 error_log <- file.path(error_dir, "errors.log") warning_log <- file.path(error_dir, "warnings.log") # 提取当前脚本的文件名 script_name <- basename(script_path) # 捕获执行过程中的错误与警告 result <- tryCatch({ # 捕获警告并记录,可选择是否保留控制台输出 withCallingHandlers({ source(script_path) }, warning = function(w) { # 构造带时间戳和脚本名的警告信息 log_content <- sprintf("[%s] 脚本: %s - 警告: %s\n", format(Sys.time(), "%Y-%m-%d %H:%M:%S"), script_name, conditionMessage(w)) # 追加写入警告日志 write(log_content, file = warning_log, append = TRUE) # 若不需要在控制台显示警告,可删除此行 invokeRestart("muffleWarning") }) }, error = function(e) { # 构造带时间戳和脚本名的错误信息 log_content <- sprintf("[%s] 脚本: %s - 错误: %s\n", format(Sys.time(), "%Y-%m-%d %H:%M:%S"), script_name, conditionMessage(e)) # 追加写入错误日志 write(log_content, file = error_log, append = TRUE) # 返回错误对象,便于后续批量处理时排查 return(e) }) return(result) } # 批量运行脚本的辅助函数 batch_run <- function(script_paths) { lapply(script_paths, function(path) { cat(sprintf("执行中: %s\n", basename(path))) RunScript2(path) }) } # 使用示例 # my_scripts <- c("./scripts/script1.R", "./scripts/script2.R") # batch_run(my_scripts)
关键细节说明
- 路径处理:用
getwd()获取当前主工作路径,dir.create确保errors目录存在,即使目录已存在也不会抛出警告。 - 日志关联脚本:通过
basename(script_path)提取脚本文件名,每条日志都明确标记来源脚本,同时添加时间戳便于追溯。 - 避免close报错:不再提前打开文件句柄,而是在捕获到错误/警告时直接以追加模式写入文件,写入完成后自动关闭,从根源避免未打开文件就执行close的错误。
- 日志隔离:错误和警告分别写入独立文件,追加模式保证每次运行的日志都会保留,不会覆盖历史记录。
- 警告控制:保留
invokeRestart("muffleWarning")时,警告仅写入日志不显示在控制台;删除此行则同时在控制台输出和日志记录。
内容的提问来源于stack exchange,提问作者Joe Crozier
相关产品推荐
相关产品推荐

