diff --git a/.travis.yml b/.travis.yml index 7c59158..2aa8088 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,9 @@ sudo: false cache: - packages +apt_packages: + - libgit2-dev + r_packages: - logging - futile.logger diff --git a/DESCRIPTION b/DESCRIPTION index 3255958..bf9c8a0 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -35,7 +35,8 @@ Suggests: callr, txtq, botor, - R.utils + R.utils, + syslognet Enhances: logging, futile.logger, diff --git a/NAMESPACE b/NAMESPACE index 154b44f..eca2fae 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -17,6 +17,7 @@ export(appender_slack) export(appender_stderr) export(appender_stdout) export(appender_syslog) +export(appender_syslognet) export(appender_tee) export(appender_telegram) export(colorize_by_log_level) @@ -39,6 +40,7 @@ export(layout_json) export(layout_json_parser) export(layout_logging) export(layout_simple) +export(layout_syslognet) export(log_appender) export(log_debug) export(log_error) diff --git a/R/appenders.R b/R/appenders.R index 58994db..8bbaf41 100644 --- a/R/appenders.R +++ b/R/appenders.R @@ -255,6 +255,39 @@ appender_syslog <- function(identifier, ...) { } +#nocov start +#' Send log messages to a network syslog server +#' @param identifier program/function identification (string). +#' @param server machine where syslog daemon runs (string). +#' @param port port where syslog daemon listens (integer). +#' +#' @return A function taking a \code{lines} argument. +#' @export +#' @note This functionality depends on the \pkg{syslognet} package. +#' @examples \dontrun{ +#' if (requireNamespace("syslognet", quietly = TRUE)) { +#' log_appender(appender_syslognet("test_app", 'remoteserver')) +#' log_info("Test message.") +#' } +#' } +appender_syslognet <- function(identifier, server, port = 601L) { + fail_on_missing_package('syslognet') + force(identifier) + force(server) + force(port) + structure( + function(lines) { + sev <- attr(lines, 'severity', exact = TRUE) + for (line in lines) { + syslognet::syslog(line, sev, app_name = identifier, server = server, port = port) + } + }, + generator = deparse(match.call()) + ) +} +#nocov end + + #' Send log messages to a Amazon Kinesis stream #' @param stream name of the Kinesis stream #' @return function taking \code{lines} and optional \code{partition_key} argument diff --git a/R/layouts.R b/R/layouts.R index c813a00..f82e6b4 100644 --- a/R/layouts.R +++ b/R/layouts.R @@ -154,7 +154,7 @@ layout_logging <- structure(function(level, msg, namespace = NA_character_, attr(level, 'level'), ':', ifelse(meta$ns == 'global', '', meta$ns), ':', msg) -}, generator = quote(layout_simple())) +}, generator = quote(layout_logging())) #' Format a log message with \code{glue} @@ -256,3 +256,33 @@ layout_json_parser <- function(fields = c('time', 'level', 'ns', 'ans', 'topenv' }, generator = deparse(match.call())) } + + +#nocov start +#' Format a log record for syslognet +#' +#' Format a log record for syslognet. +#' This function converts the logger log level to a +#' log severity level according to RFC 5424 "The Syslog Protocol". +#' +#' @inheritParams layout_simple +#' @return A character vector with a severity attribute. +#' @export +layout_syslognet <- structure( + function(level, msg, namespace = NA_character_, + .logcall = sys.call(), .topcall = sys.call(-1), .topenv = parent.frame()) { + ret <- paste(attr(level, 'level'), msg) + attr(ret, 'severity') <- switch( + attr(level, 'level', exact = TRUE), + 'FATAL' = 'CRITICAL', + 'ERROR' = 'ERR', + 'WARN' = 'WARNING', + 'SUCCESS' = 'NOTICE', + 'INFO' = 'INFO', + 'DEBUG' = 'DEBUG', + 'TRACE' = 'DEBUG') + return(ret) + }, + generator = quote(layout_syslognet()) +) +#nocov end diff --git a/man/appender_syslognet.Rd b/man/appender_syslognet.Rd new file mode 100644 index 0000000..3844690 --- /dev/null +++ b/man/appender_syslognet.Rd @@ -0,0 +1,32 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/appenders.R +\name{appender_syslognet} +\alias{appender_syslognet} +\title{Send log messages to a network syslog server} +\usage{ +appender_syslognet(identifier, server, port = 601L) +} +\arguments{ +\item{identifier}{program/function identification (string).} + +\item{server}{machine where syslog daemon runs (string).} + +\item{port}{port where syslog daemon listens (integer).} +} +\value{ +A function taking a \code{lines} argument. +} +\description{ +Send log messages to a network syslog server +} +\note{ +This functionality depends on the \pkg{syslognet} package. +} +\examples{ +\dontrun{ +if (requireNamespace("syslognet", quietly = TRUE)) { + log_appender(appender_syslognet("test_app", 'remoteserver')) + log_info("Test message.") +} +} +} diff --git a/man/layout_syslognet.Rd b/man/layout_syslognet.Rd new file mode 100644 index 0000000..894fbc4 --- /dev/null +++ b/man/layout_syslognet.Rd @@ -0,0 +1,36 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/layouts.R +\name{layout_syslognet} +\alias{layout_syslognet} +\title{Format a log record for syslognet} +\usage{ +layout_syslognet( + level, + msg, + namespace = NA_character_, + .logcall = sys.call(), + .topcall = sys.call(-1), + .topenv = parent.frame() +) +} +\arguments{ +\item{level}{level of log message.} + +\item{msg}{string of log message.} + +\item{namespace}{namespace.} + +\item{.logcall}{logcall; see \code{\link[logger]{layout_blank}}.} + +\item{.topcall}{topcall; see \code{\link[logger]{layout_blank}}.} + +\item{.topenv}{topenv; ; see \code{\link[logger]{layout_blank}}.} +} +\value{ +A character vector with a severity attribute. +} +\description{ +Format a log record for syslognet. +This function converts the logger log level to a +log severity level according to RFC 5424 "The Syslog Protocol". +}