-
Notifications
You must be signed in to change notification settings - Fork 46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
return value? #26
Comments
Yeah, this is a great idea, thanks 👍 I'm towards returning the formatted message before running through the layout function, so "message of badness 42" in this case, but might be indeed cleaner to return the actual log record ... Let me do some research on how others are doing this and please let me know meanwhile if you have any further thoughts. |
One beneficial side-effect for returning the entire formatted string is that testing becomes a little more literal. I recognize you already have tests set up so you don't need new ones, but perhaps: testthat::expect_true(grepl(ptn, logger::log_info(...))) where |
Yeah, that's a great point
Actually, now I have a (I think) great idea of invisibly returning an
object instead of a string -- that includes the formatted message + full
log record with the layout and a bunch of other things
…--
Sent from a mobile phone with an annoying input interface, pls excuse my
brevity/spelling issues.
On Fri, Jul 26, 2019, 18:37 r2evans ***@***.***> wrote:
One beneficial side-effect for returning the entire formatted string is
that testing becomes a little more literal. I recognize you already have
tests set up so you don't need new ones, but perhaps:
testthat::expect_true(grepl(ptn, logger::log_info(...)))
where ptn checks for a post-formatting feature (perhaps including
timestamp stuff).
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#26?email_source=notifications&email_token=AADZA6BW4C4EMOFL5NAKCITQBMR57A5CNFSM4ICTRRSKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD25DQFQ#issuecomment-515520534>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AADZA6GLVPXZON5ZNCX5BL3QBMR57ANCNFSM4ICTRRSA>
.
|
Returning a non- # logger package code
log_level <- function(level, ...) {
# normal stuff here
ret <- list(..., ..., ...)
class(ret) <- c("logger", "list")
return(ret)
}
as.character.logger <- function(x, ...) {
# abuses the fact that R looks anyway, even though base::as.character is not S3
# something here
}
print.logger <- function(x, ...) {
# something here
}
# code using this package
if (x < badcondition) {
msg <- logger::log_fatal("message of badness {x}")
stop(as.character(msg))
} Or were you thinking of something like: log_level <- function(level, ...) {
# normal stuff here
ret <- as.character(...)
class(ret) <- c("logger", "character")
attr(ret, "logger_obj") <- myobj
return(ret)
}
print.logger <- function(x, ...) {
obj <- attr(x, "logger_obj")
# print something meaningful from that ...
# then perhaps do a normal-print of the original string
print.default(`attr<-`(x, "logger_obj", NULL))`
} |
Because this object would be returned invisibly, the > log_info(42)
INFO [timestamp] 42
[1] "42" I'm not sure if anyone would actually call as.character.logger <- function(x, ...) { x$$formatted_message }
stop(as.character(logger::log_fatal("message of badness {x}"))) or even without a helper: stop(logger::log_fatal("message of badness {x}")$formatted_message) |
I don't disagree that it won't normally be called with As I was generating suggested code for this comment, I realized that this is complicated by the nature of iterating over
(BTW: am I wrong, or does |
The returned object can be as complex as needed I think, I don't see any issues there -- but will do some benchmarks. |
I think your use of |
@daroczig, I see you've been merging PRs recently. Is our above discussion enough or do you need it to be formalized into a PR? (Assuming of course that you still see value in this FR.) Thanks! |
Yeah, I tried to dedicate some time to this project again, but no promises 🤐 Thanks for the bump here, though! This is a really cool FR, so I'd like to get this done - but definitely larger task than all the other minor things I got done recently in this package. In short, any help is appreciated, otherwise I'll try to get a PR together for review in the Dec holiday season. |
I hope the PR makes sense. |
Very much, thank you! I'm going through this today or tomorrow with the goal of merging by the end of the week and also making this part of a CRAN release planned by EOW. |
Hi, sorry for posting on this older issue, it just seemed more relevant than making a new one. I am working with a docker container on AWS lambda, and was using logger for structured logging to AWS CloudWatch (basically only the Now that I updated to 0.3.0 in my docker image I am getting errors that Reprex: logger 0.2.2 library(jsonlite) # 1.8.8
library(logger) # 0.2.2
toJSON(log_info("test"))
# INFO [2024-04-09 09:24:53] test
# {} logger 0.3.0 library(jsonlite) # 1.8.8
library(logger) # 0.3.0
toJSON(log_info("test"))
# INFO [2024-04-09 09:24:30] test
# Error: No method asJSON S3 class: logger |
Up front, library(logger)
jsonlite::toJSON(log_info("test")[[1]]$record)
# INFO [2024-04-09 09:16:45] test
# ["INFO [2024-04-09 09:16:45] test"]
log_layout(layout_json())
jsonlite::toJSON(log_info("test")[[1]]$record)
# {"time":"2024-04-09 09:17:00","level":"INFO","ns":"global","ans":"global","topenv":"R_GlobalEnv","fn":"force","node":"d2xps","arch":"x86_64","os_name":"Linux","os_release":"6.5.0-27-generic","os_version":"#28-Ubuntu SMP PREEMPT_DYNAMIC Thu Mar 7 18:21:00 UTC 2024","pid":29118,"user":"r2","msg":"test"}
# ["{\"time\":\"2024-04-09 09:17:00\",\"level\":\"INFO\",\"ns\":\"global\",\"ans\":\"global\",\"topenv\":\"R_GlobalEnv\",\"fn\":\"force\",\"node\":\"d2xps\",\"arch\":\"x86_64\",\"os_name\":\"Linux\",\"os_release\":\"6.5.0-27-generic\",\"os_version\":\"#28-Ubuntu SMP PREEMPT_DYNAMIC Thu Mar 7 18:21:00 UTC 2024\",\"pid\":29118,\"user\":\"r2\",\"msg\":\"test\"}"] If you look at the return value from str(log_info("test"))
# {"time":"2024-04-09 09:17:29","level":"INFO","ns":"global","ans":"global","topenv":"R_GlobalEnv","fn":"str","node":"d2xps","arch":"x86_64","os_name":"Linux","os_release":"6.5.0-27-generic","os_version":"#28-Ubuntu SMP PREEMPT_DYNAMIC Thu Mar 7 18:21:00 UTC 2024","pid":29118,"user":"r2","msg":"test"}
# List of 1
# $ default:List of 6
# ..$ level : 'loglevel' int 400
# .. ..- attr(*, "level")= chr "INFO"
# ..$ namespace: chr "global"
# ..$ params :List of 1
# .. ..$ : chr "test"
# ..$ handlers :List of 3
# .. ..$ formatter:function (..., .logcall = sys.call(), .topcall = sys.call(-1), .topenv = parent.frame())
# .. .. ..- attr(*, "generator")= language formatter_glue()
# .. ..$ layout :function (level, msg, namespace = NA_character_, .logcall = sys.call(), .topcall = sys.call(-1), .topenv = parent.frame())
# .. .. ..- attr(*, "generator")= chr "layout_json()"
# .. ..$ appender :function (lines)
# .. .. ..- attr(*, "generator")= language appender_console()
# ..$ message : chr "test"
# ..$ record : Named chr "{\"time\":\"2024-04-09 09:17:29\",\"level\":\"INFO\",\"ns\":\"global\",\"ans\":\"global\",\"topenv\":\"R_Global"| __truncated__
# .. ..- attr(*, "names")= chr "test"
# ..- attr(*, "class")= chr "logger" The list is because |
Thanks @r2evans , that already clarifies a lot - I should have been a bit more clear in my problem description as well. I am actually getting the problem because to interface with AWS lambda I am calling the lambda API using if (encode == "json") {
body_raw(jsonlite::toJSON(body, auto_unbox = TRUE, digits = 22),
"application/json")
} I have no option to pass along arguments to |
Have you considered invisibly returning the log message?
I find myself periodically doing something like:
I can form the message once and use it in both
logger::log_fatal
andstop
, but (1) I might like to take advantage oflogger
's formatting methodologies (e.g.,glue
or json); and (2) I think a more straight-forward approach is something like:(This if course applies to other loggers, not just
log_fatal
.)I'd think there are two good options for exactly what to return:
"message of badness 42"
, before some of the final formatting ... or"[2019-07-12 17:04:42] FATAL message of badness 42"
, the literal full log entryThoughts?
The text was updated successfully, but these errors were encountered: