-
Notifications
You must be signed in to change notification settings - Fork 6
add more LogfireConverter
#110
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
base: main
Are you sure you want to change the base?
Conversation
The first thing I noticed, it that just simply trying to implement the Trait was not possible because of the orphan rule (Value is in opentelemetry and From is in std, and I tried implementing that in logfire). So then, I tried changing it from the opentelemetry, but that required changing the proto file, which sounded a bit too much, and I also noticed that converters would be necessary, because Rust have more primitive types than proto. Finally, I tried I am aware that this is probably not the most efficient algorithm, because in the end I have to convert a variable twice, once to a Similar to the previous implementation, in case of overflow, the variable is actually a The issue #58, only mentioned To be very thoroughly, I also added some tests, but I noticed the a lot of the tests were repeating let output = Arc::new(Mutex::new(Vec::new()));
let console_options = ConsoleOptions {
target: Target::Pipe(output.clone()),
..ConsoleOptions::default().with_min_log_level(Level::INFO)
};
let logfire = crate::configure()
.local()
.send_to_logfire(false)
.with_console(Some(console_options))
.with_default_level_filter(tracing::level_filters::LevelFilter::TRACE)
.finish()
.unwrap();
let guard = crate::set_local_logfire(logfire); so I added that to a helper function. The final change was to update the examples, where no more casting was required. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR, really appreciate the help!
I would strongly prefer we try to use try_from
first, because it'll be cheap to fail to create an i64
from an out-of-bounds integer.
Going unconditionally via strings and then attempting to parse them will probably introduce major overheads for users using logfire to capture simple numeric values.
crate::info!("an i16: {value}", value = 8i16); | ||
crate::info!("an i32: {value}", value = 9i32); | ||
crate::info!("an i64: {value}", value = 10i64); | ||
crate::info!("an i128: {value}", value = 10i128); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe let's use debug format so that the fact these are being sent as strings is captured in the test.
crate::info!("an i128: {value}", value = 10i128); | |
crate::info!("an i128: {value:?}", value = 10i128); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only one that actually changes is the char
:
from an char: a
to an char: 'a'
The number cases are the same with and without :?
src/macros/impl_.rs
Outdated
let value_string = value.to_string(); | ||
if let Ok(value) = value_string.parse::<i64>() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why was i64::try_from
no longer possible? I think all of these types should implement that conversion.
Maybe rather than a generic on T
(those can be problematic, we only really ever are allowed one) can we do this with a macro that adds a concrete implementation?
e.g.
impl_into_i64_value!(usize); // expands to an implementation for `LogfireConverter<usize>`
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried it again, and remember why I did something else. So the problem is that the type become ambiguous for the compiler, so cases like:
let _ = log!(Level::INFO, "int_attr_log", num = 42);
which can be fixed by let _ = log!(Level::INFO, "int_attr_log", num = 42i64);
Therefore, for those types of test case, I change to i64
when ambiguous. I chose i64
since it is the default from open telemetry.
Another small issue is that for the cases that don't overflow like u8
, u16
, u32
, i8
, i16
, i32
, the compiler complain saying: note: this pattern will always match, so the if let is useless
.
To solve that, then I created the following two macros: impl_into_from_i64_value
and impl_into_try_into_i64_value
.
I fixed the doc tests. I also have to admit that not all tests pass on failures: |
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
This adds more
LogfireConverter
to address #58, and many other types.I also took the liberty to update the test of the macro a bit, to avoid repetition, and added tests for many rust types for
log!
The examples also update to show that you can actually use any time.