Skip to content

Commit

Permalink
Fixes #18 Duplicated warnings and messages (info) in log and output. …
Browse files Browse the repository at this point in the history
…Includes refactorings to prepare more new features. Added timestamp and dump.file.name to last.tryCatch.result
  • Loading branch information
aryoda committed Dec 3, 2017
1 parent e15091e commit 7c8e245
Show file tree
Hide file tree
Showing 19 changed files with 564 additions and 123 deletions.
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: tryCatchLog
Title: Advanced tryCatch function
Version: 0.9.8
Version: 0.9.9
Authors@R: person("Jürgen", "Altfeld", email = "[email protected]", role = c("aut", "cre", "cph"))
Description: Advanced tryCatch function for better error handling with logging and a stack trace with source code references.
Imports:
Expand Down
15 changes: 13 additions & 2 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,21 @@ This file describes the major changes of bug fixes in the package "tryCatchLog"
--------------------------------------------------------------------------------
## upcoming (planned to be released in the next version)

* Fixing issue #18 (duplicated conditions)
* wait and see...
* stacked tryCatchLog calls ignore dump and silent params after first handling
* rename tryCatchLog argument "dump.errors.to.file" to "dump.to.file" or similar (more precise name required!)
--------------------------------------------------------------------------------

## Version 0.9.9 (Dec. 03, 2017)

* Fixed bug #18 (duplicated errors, warnings and messages in stacked `tryCatchLog` calls
* Improved documentation of `last.tryCatch.result`
* build.log.output: Added arguments for incl.timestamp + incl.severity
as option to suppress redundant output if a logging framework is used
* Open issue: R CMD check results in one warning (false positive: missing documentation entries for `build.log.output`)




## Version 0.9.8 (Nov. 23, 2017)

* Exported function `build.log.output` to create a single string suited as logging output from `last.tryCatchLog.result`
Expand Down
33 changes: 22 additions & 11 deletions R/build_log_entry.R
Original file line number Diff line number Diff line change
Expand Up @@ -21,33 +21,44 @@
#'
#' The serverity level should correspond to the condition class.
#'
#' @param severity severity level of the log entry ((ERROR, WARNING, MESSAGE etc.)
#' @param msg.text the message text of the thrown condition
#' @param timestamp logging timestamp as \code{\link{POSIXct}} (normally by calling \code{\link{Sys.time}})
#' @param severity severity level of the log entry ((ERROR, WARN, INFO etc.)
#' @param msg.text Logging message (e. g. error message)
#' @param call.stack a call stack created by \code{\link{sys.calls}}
#' @param omit.last.items the number of stack trace items to ignore (= last x calls) in
#' the passed \code{call.stack} since they are caused by using \code{tryCatchLog}
#' @param dump.file.name name of the created dump file (leave empty if the \code{\link{tryCatchLog}}
#' argument \code{dump.errors.to.file} is \code{FALSE}
#' @param omit.call.stack.items the number of stack trace items to ignore (= last x calls) in
#' the passed \code{call.stack} since they are caused by using \code{tryCatchLog}
#'
#' @return An object of class \code{tryCatchLog.log.entry} and \code{\link{data.frame}} with one and the following columns:
#' \enumerate{
#' \item{severity - the serverity level of the log entry (ERROR, WARNING, MESSAGE)}
#' \item{log.message - the message text of the log entry}
#' \item{timestamp - creation date and time of the logging entry}
#' \item{severity - the serverity level of the log entry (ERROR, WARN, INFO etc.)}
#' \item{msg.text - the message text of the log entry}
#' \item{compact.stack.trace - the short stack trace containing only entries with source code
#' references down to line of code that has thrown the condition}
#' \item{full.stack.trace - the full stack trace with all calls down to the line of code that
#' has thrown the condition (including calls to R internal functions
#' and other functions even when the source code in not available).}
#' \item{dump.file.name - name of the created dump file (if any)}
#' }
#'
#' @seealso \code{\link{last.tryCatchLog.result}}
#' \code{\link{build.log.output}}
#'
#' @note THIS IS A PACKAGE INTERNAL FUNCTION AND THEREFORE NOT EXPORTED.
build.log.entry <- function(severity, log.message, call.stack, omit.last.items = 0) {
build.log.entry <- function(timestamp, severity, msg.text, call.stack, dump.file.name, omit.call.stack.items = 0) {

log.entry <- data.frame(severity = severity,
msg.text = log.message,
compact.stack.trace = get.pretty.call.stack(call.stack, omit.last.items, compact = TRUE),
full.stack.trace = get.pretty.call.stack(call.stack, omit.last.items),
stopifnot(inherits(timestamp, "POSIXct"))



log.entry <- data.frame(timestamp = timestamp,
severity = severity,
msg.text = msg.text,
compact.stack.trace = get.pretty.call.stack(call.stack, omit.call.stack.items, compact = TRUE),
full.stack.trace = get.pretty.call.stack(call.stack, omit.call.stack.items),
dump.file.name = dump.file.name,
stringsAsFactors = FALSE
)

Expand Down
39 changes: 27 additions & 12 deletions R/build_log_output.R
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,19 @@

#' Creates a single string suited as logging output
#'
#' To view the formatted output print the logging output in a console use \code{\link{cat}}
#' (instead of printing the output with \code{\link{print}} which shows the newline escape codes).
#'
#' @param log.results A \code{data.frame} and member of the class \code{tryCatchLog.log.entry}
#' with log entry rows as returned by \code{\link{last.tryCatchLog.result}}
#' containing the logging information to be prepared for the logging output.
#' @param include.full.call.stack Flag of type \code{\link{logical}}:
#' Shall the full call stack be included in the log output? Since the full
#' call stack may be very long it can be omitted by passing \code{FALSE}.
#' @param include.severity \code{logical} switch if the severity level (e. g. ERROR) shall be
#' included in the output
#' @param include.timestamp \code{logical} switch if the timestamp of the catched condition shall be
#' included in the output
#'
#' @return A ready to use logging output with stack trace
#' (as \code{character})
Expand All @@ -36,7 +43,9 @@
#'
#' @note Supports also a single row created by the package internal function \code{\link{build.log.entry}}
#' as \code{log.results} argument.
build.log.output <- function(log.results, include.full.call.stack = TRUE) {
build.log.output <- function(log.results, include.full.call.stack = TRUE, include.severity = TRUE, include.timestamp = FALSE) {

# TODO Add arguments for incl.timestamp + incl.severity later (redundant output if a logging framework is used!)

stopifnot("data.frame" %in% class(log.results))

Expand All @@ -48,17 +57,23 @@ build.log.output <- function(log.results, include.full.call.stack = TRUE) {
while (i <= NROW(log.results)) {

res <- paste0(res,
"[", log.results$severity[i], "] ", log.results$msg.text[i],
"\n\n",
"Compact call stack:",
"\n",
log.results$compact.stack.trace[i],
"\n\n",
if (include.full.call.stack) {paste0("Full call stack:",
"\n",
log.results$full.stack.trace[i],
"\n\n")
} else ""
if (include.timestamp)
format(log.results$timestamp[i], "%Y-%m-%d %H:%M:%S "),
if (include.severity)
paste0("[", log.results$severity[i], "] "),
log.results$msg.text[i],
"\n\n",
if (nchar(log.results$dump.file.name[i]) > 0)
paste0("Created dump file: ", log.results$dump.file.name[i], "\n\n"),
"Compact call stack:",
"\n",
log.results$compact.stack.trace[i],
"\n\n",
if (include.full.call.stack) {paste0("Full call stack:",
"\n",
log.results$full.stack.trace[i],
"\n\n")
}
)

i <- i + 1
Expand Down
Binary file added R/dump_20171203_000858.rda
Binary file not shown.
56 changes: 56 additions & 0 deletions R/is_duplicated_log_entry.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# ***************************************************************************
# Copyright (C) 2016 Juergen Altfeld ([email protected])
# ---------------------------------------------------------------------------
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# ***************************************************************************



#' Check if a new log entry would be a duplicate of on an already existing log entry
#'
#' The \code{log.entry} is checked against the existing log entries from
#' \code{\link{last.tryCatchLog.result}} using the following columns:
#' \enumerate{
#' \item{msg.text}
#' \item{full.stack.trace}
#' }
#'
#' @note Required function to fix issue # 18
#' (\url{https://github.com/aryoda/tryCatchLog/issues/18})
#'
#' @param log.entry A \code{data.frame} with the new log entry (exactly one row)
#'
#' @return \code{TRUE} if the \code{log.entry} is a duplicate, else \code{FALSE}
#'
#' @seealso \code{\link{last.tryCatchLog.result}},
#' \code{\link{build.log.entry}}
is.duplicated.log.entry <- function(log.entry) {

if (is.null(log.entry))
return(TRUE) # an empty entry is useless - treat it like a duplicate

stopifnot("tryCatchLog.log.entry" %in% class(log.entry))



log <- last.tryCatchLog.result()

if (NROW(log) < 1)
res <- FALSE
else
res <- any(log$msg.text == log.entry$msg.text & log$full.stack.trace == log.entry$full.stack.trace)

return(res)

}
12 changes: 8 additions & 4 deletions R/last_tryCatchLog_result.R
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,19 @@
#' @return the logging result of the last call to \code{\link{tryCatchLog}} or \code{\link{tryLog}}
#' as \code{\link{data.frame}} comprised of one row per logged condition with these columns:
#' \enumerate{
#' \item{severity - the serverity level of the log entry (ERROR, WARNING, MESSAGE) as \code{character}}
#' \item{log.message - the message text of the log entry as \code{character}}
#' \item{timestamp - creation date and time of the logging entry}
#' \item{severity - the serverity level of the log entry (ERROR, WARN, INFO etc.)}
#' \item{msg.text - the message text of the log entry}
#' \item{compact.stack.trace - the short stack trace containing only entries with source code
#' references down to line of code that has thrown the condition as \code{character}}
#' references down to line of code that has thrown the condition}
#' \item{full.stack.trace - the full stack trace with all calls down to the line of code that
#' has thrown the condition (including calls to R internal functions
#' and other functions even when the source code in not available) as \code{character}}
#' and other functions even when the source code in not available).}
#' \item{dump.file.name - name of the created dump file (if any)}
#' }
#'
#' If no condition is logged at all an empty \code{data.table} is returned.
#'
#' @seealso \code{\link{tryCatchLog}},
#' \code{\link{tryLog}}
#'
Expand Down
Loading

0 comments on commit 7c8e245

Please sign in to comment.