Skip to content

Commit 51b8bb1

Browse files
authored
Merge pull request #60 from s-fleck/rawMsg
add hidden .rawMsg property to LogEvent
2 parents c0cf4c1 + 0f23727 commit 51b8bb1

File tree

14 files changed

+178
-97
lines changed

14 files changed

+178
-97
lines changed

.Rbuildignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@
1717
^\.httr-oauth$
1818
^revdep$
1919
^.github$
20+
^CRAN-SUBMISSION$

CRAN-SUBMISSION

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Version: 0.4.4
2+
Date: 2022-09-05 21:01:18 UTC
3+
SHA: c725c929678ac9d18a9f45a42f1147d41b7a13d5

NEWS.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@
44
`{knitr}` rendering process, log messages are now output to `stderr` instead
55
of `stdout` by default, to avoid polluting markdown documents (#62, thx @gadenbuie).
66

7+
* BREAKING: added `rawMsg` property to LogEvents to store message without
8+
string interpolation (e.g. that still contains the placeholders from
9+
`sprintf()` or `glue()`). rawMessage will be added by default to json
10+
log files (#60)
11+
12+
* updated Readme
13+
14+
715
# lgr 0.4.4
816

917
* `%k` and `%K` parameters in `format.LogEvent` now work as expected when using

R/LogEvent.R

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ LogEvent <- R6::R6Class(
5353
timestamp = Sys.time(),
5454
caller = NA,
5555
msg = NA,
56+
rawMsg = msg,
5657
...
5758
){
5859
assert(inherits(logger, "Logger"), "Logger must be a <Logger> object, not a ", class_fmt(logger))
@@ -64,6 +65,7 @@ LogEvent <- R6::R6Class(
6465
assign("timestamp", timestamp, self)
6566
assign("caller", caller, self)
6667
assign("msg", msg, self)
68+
assign("rawMsg", rawMsg, self)
6769

6870
# custom values
6971
if (!missing(...)){
@@ -94,19 +96,22 @@ LogEvent <- R6::R6Class(
9496

9597
#' @field .logger [Logger]. A reference to the Logger that created the
9698
#' event (equivalent to `get_logger(event$logger)`).
97-
.logger = NULL
99+
.logger = NULL,
100+
101+
#' @field rawMsg `character`. The raw log message without string
102+
#' interpolation.
103+
rawMsg = NULL
98104
),
99105

100106
active = list(
101107

102108
#' @field values `list`. All values stored in the `LogEvent`, including
103109
#' all *custom fields*, but not including `event$.logger`.
104110
values = function(){
105-
fixed_vals <- c("level", "timestamp", "logger", "caller", "msg")
111+
fixed_vals <- c("level", "timestamp", "logger", "caller", "msg", "rawMsg")
106112
custom_vals <- setdiff(
107113
names(get(".__enclos_env__", self)[["self"]]),
108-
c(".__enclos_env__", "level_name", "initialize", "clone", "values",
109-
".logger")
114+
c(".__enclos_env__", "level_name", "initialize", "clone", "values", ".logger")
110115
)
111116
valnames <- union(fixed_vals, custom_vals) # to enforce order of fixed_vals
112117
mget(valnames, envir = self)
@@ -329,6 +334,7 @@ as_tibble.LogEvent <- function(
329334
#' multiple threads.}
330335
#' \item{`%c`}{the calling function}
331336
#' \item{`%m`}{the log message}
337+
#' \item{`%r`}{the raw log message (without string interpolation)
332338
#' \item{`%f`}{all custom fields of `x` in a pseudo-JSON like format that is
333339
#' optimized for human readability and console output}
334340
#' \item{`%j`}{all custom fields of `x` in proper JSON. This requires that you
@@ -427,7 +433,7 @@ format.LogEvent <- function(
427433
fmt,
428434
valid_tokens = paste0(
429435
"%",
430-
c("t", "p", "c", "m", "l", "L", "n", "f", "j", "k", "K", "g"))
436+
c("t", "p", "c", "m", "r", "l", "L", "n", "f", "j", "k", "K", "g"))
431437
)
432438

433439
# format
@@ -444,6 +450,7 @@ format.LogEvent <- function(
444450
"%K" = colorize_levels(lvls, colors, transform = function(.) toupper(strtrim(., 1))),
445451
"%t" = format(get("timestamp", envir = x), format = timestamp_fmt),
446452
"%m" = get("msg", envir = x),
453+
"%r" = get("rawMsg", envir = x),
447454
"%c" = get("caller", envir = x),
448455
"%g" = get("logger", envir = x),
449456
"%p" = Sys.getpid(),
@@ -591,4 +598,4 @@ tokenize_format <- function(
591598

592599
# globals --------------------------------------------------------
593600

594-
DEFAULT_FIELDS <- c("level", "timestamp", "logger", "caller", "msg")
601+
DEFAULT_FIELDS <- c("level", "timestamp", "logger", "caller", "msg", "rawMsg")

R/Logger.R

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -226,14 +226,16 @@ Logger <- R6::R6Class(
226226
}
227227

228228
force(caller)
229+
rawMsg <- msg
229230

230231
if (missing(...)){
231232
vals <- list(
232233
logger = self,
233234
level = level,
234235
timestamp = timestamp,
235236
caller = caller,
236-
msg = msg
237+
msg = msg,
238+
rawMsg = rawMsg
237239
)
238240
} else {
239241
dots <- list(...)
@@ -245,7 +247,8 @@ Logger <- R6::R6Class(
245247
level = level,
246248
timestamp = timestamp,
247249
caller = caller,
248-
msg = msg
250+
msg = msg,
251+
rawMsg = rawMsg
249252
)
250253
} else {
251254
not_named <- vapply(names(dots), is_blank, TRUE, USE.NAMES = FALSE)
@@ -259,7 +262,8 @@ Logger <- R6::R6Class(
259262
level = level,
260263
timestamp = timestamp,
261264
caller = caller,
262-
msg = msg
265+
msg = msg,
266+
rawMsg = rawMsg
263267
),
264268
dots[!not_named]
265269
)
@@ -882,6 +886,11 @@ LoggerGlue <- R6::R6Class(
882886
"Can only utilize vectorized logging if log level is the same for all entries"
883887
)
884888

889+
assert(
890+
!missing(...),
891+
"No log message or structured logging fields supplied"
892+
)
893+
885894
dots <- list(...)
886895

887896
if ("msg" %in% names(dots)){
@@ -909,6 +918,7 @@ LoggerGlue <- R6::R6Class(
909918
}
910919
})
911920

921+
rawMsg <- dots[[1]]
912922
msg <- do.call(glue::glue, args = c(dots_msg, list(.envir = .envir)))
913923

914924
# Check if LogEvent should be created
@@ -921,22 +931,21 @@ LoggerGlue <- R6::R6Class(
921931

922932
force(caller)
923933

924-
if (missing(...)){
925-
stop("No log message or structured logging fields supplied")
926-
} else {
927-
custom_fields <- !(grepl("^\\.", names(dots)) | is_blank(names(dots)))
934+
# Create list that contains all values equired for the log event
935+
custom_fields <- !(grepl("^\\.", names(dots)) | is_blank(names(dots)))
936+
937+
vals <- c(
938+
list(
939+
logger = self,
940+
level = level,
941+
timestamp = timestamp,
942+
caller = caller,
943+
msg = msg,
944+
rawMsg = rawMsg
945+
),
946+
dots[custom_fields]
947+
)
928948

929-
vals <- c(
930-
list(
931-
logger = self,
932-
level = level,
933-
timestamp = timestamp,
934-
caller = caller,
935-
msg = msg
936-
),
937-
dots[custom_fields]
938-
)
939-
}
940949

941950
# This code looks really weird, but it really is just replacing all
942951
# instances of [[ with get() for minimal overhead. We want event

R/basic_config.R

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -97,17 +97,20 @@ basic_config <- function(
9797
if (!is.null(file)){
9898
ext <- tools::file_ext(file)
9999

100-
if (identical(tolower(ext), "json")){
101-
stop(
102-
"Please use `.jsonl` and not `.json` as file extension for JSON log",
103-
"files. The reason is that that JSON files created",
104-
"by lgr are not true JSON files but JSONlines files.",
105-
"See https://jsonlines.org/ for more infos."
106-
)
100+
if (tolower(ext) %in% c("jsonl", "json")){
101+
102+
if (identical(tolower(ext), "json")){
103+
warning(
104+
"Please use `.jsonl` and not `.json` as file extension for JSON log ",
105+
"files. The reason is that that JSON files created ",
106+
"by lgr are not true JSON files but JSONlines files. ",
107+
"See https://jsonlines.org/ for more infos."
108+
)
109+
}
107110

108-
} else if (identical(tolower(ext), "jsonl")){
109-
if (!is.null(fmt) && !identical(fmt, default_fmt))
111+
if (!is.null(fmt) && !identical(fmt, default_fmt)){
110112
warning("`fmt` is ignored if `file` is a '.jsonl' file")
113+
}
111114

112115
l$add_appender(
113116
name = "file",

README.Rmd

Lines changed: 25 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ basic_config(console_connection = stdout()) # ensure default config
1919
# lgr
2020

2121
[![CRAN status](https://www.r-pkg.org/badges/version/lgr)](https://cran.r-project.org/package=lgr)
22-
[![Lifecycle: maturing](https://img.shields.io/badge/lifecycle-maturing-blue.svg)](https://lifecycle.r-lib.org/articles/stages.html)
22+
[![Lifecycle: maturing](https://img.shields.io/badge/lifecycle-stable-green.svg)](https://lifecycle.r-lib.org/articles/stages.html)
2323

2424
lgr is a logging package for R built on the back of
2525
[R6](https://github.com/r-lib/R6) classes. It is designed to be flexible,
@@ -144,14 +144,25 @@ file.remove(logfile)
144144

145145
## Development status
146146

147-
lgr in general is stable and safe for use, but **the following features are still experimental**:
147+
lgr is stable and safe for use. I've been using it in production code for
148+
several years myself. There has been very little recent development because
149+
it's pretty stable and contains (nearly) all planned features.
148150

149-
* Database appenders which are available from the separate package
150-
[lgrExtra](https://github.com/s-fleck/lgrExtra).
151-
* yaml/json config files for loggers (do not yet support all planned features)
152-
* The documentation in general. I'm still hoping for more R6-specific features
153-
in [roxygen2](https://github.com/r-lib/roxygen2) before I invest more
154-
time in object documentation.
151+
Notable points that are not
152+
153+
* Support for config files is heavily experimental and incomplete.
154+
This is an important basic feature, but I have not yet found a great way to
155+
support this in a generic way. For now, I recommend you come up with your own
156+
solution if you need to lgr to work in a production environment that relies
157+
on config files.
158+
159+
* The documentation should be mostly complete, but is not perfect. If there's
160+
something missing or something you don't understand - please ask (for example
161+
via a github issue).
162+
163+
* Please also check out the lgrExtra package for a variety of extra appenders
164+
[lgrExtra](https://github.com/s-fleck/lgrExtra) (that might not be as stable
165+
as the main lgr package itself).
155166

156167

157168
## Dependencies
@@ -169,7 +180,6 @@ lgr comes with a long list of optional dependencies that make a wide range of
169180
appenders possible. You only need the dependencies for the Appenders you
170181
actually want to use. Care was taken to choose packages that are slim, stable,
171182
have minimal dependencies, and are well maintained :
172-
173183

174184
Extra appenders (in the main package):
175185

@@ -186,38 +196,16 @@ have minimal dependencies, and are well maintained :
186196
- [glue](https://glue.tidyverse.org/) for a more flexible formatting syntax
187197
via LoggerGlue and LayoutGlue.
188198

189-
Extra appenders via [lgrExtra](https://github.com/s-fleck/lgrExtra):
190-
191-
- [DBI](https://github.com/r-dbi/DBI) for logging to databases. lgr is
192-
confirmed to work with the following backends:
193-
- [RSQLite](https://github.com/r-dbi/RSQLite),
194-
- [RMariaDB](https://github.com/r-dbi/RMariaDB) for MariaDB and MySQL,
195-
- [RPostgres](https://cran.r-project.org/package=RPostgres),
196-
- [RJDBC](https://github.com/s-u/RJDBC) for DB2, and
197-
- [odbc](https://github.com/r-dbi/odbc) also for DB2.
198-
199-
In theory all DBI compliant database packages should work. If you
200-
are using lgr with a database backend, please report your (positive and
201-
negative) experiences, as database support is still somewhat experimental.
202-
203-
- [gmailr](https://cran.r-project.org/package=gmailr) or
204-
205-
- [sendmailR](https://cran.r-project.org/package=sendmailR) for email
206-
notifications.
207-
208-
- [RPushbullet](https://github.com/eddelbuettel/rpushbullet) for push
209-
notifications.
210-
211-
- [Rsyslog](https://cran.r-project.org/package=rsyslog) for logging to
212-
syslog on POSIX-compatible systems.
213-
214-
- [elastic](https://cran.r-project.org/package=elastic) for logging
215-
to ElasticSearch
199+
Extra appenders via lgrExtra:
216200

201+
- For support for Elasticsearch, Dynatrace, Push- and Email notifications,
202+
etc... as well as the relevant dependencies please refer to the
203+
documentation of [lgrExtra](https://github.com/s-fleck/lgrExtra)
204+
217205
Other extra features:
218206

219207
- [yaml](https://CRAN.R-project.org/package=yaml) for configuring loggers
220-
via YAML files
208+
via YAML files (experimental)
221209
- [crayon](https://github.com/r-lib/crayon) for colored console output.
222210
- [whoami](https://github.com/r-lib/whoami/blob/master/DESCRIPTION) for
223211
guessing the user name from various sources. You can also set the user name
@@ -257,8 +245,6 @@ features/appenders that you'd like to see, please feel free to post a feature
257245
request on the issue tracker.
258246

259247

260-
261-
262248
## Acknowledgement
263249

264250
* [diagrams.net](https://app.diagrams.net/) for the flow chart in the vignette

man/LogEvent.Rd

Lines changed: 5 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)