-
Notifications
You must be signed in to change notification settings - Fork 731
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
Size Based Rotating File Appender #865
Size Based Rotating File Appender #865
Conversation
7d23a15
to
36de84e
Compare
Motivation Adding an appender with max size per log file and max number of log files. Addressing tokio-rs#858 Solution Adding an appender very similar to the `RollingFileAppender`, that will base the rotation on size of log file and number of log files.
36de84e
to
c775505
Compare
All of the CI failures are due to |
Thanks @CfirTsabari, I'll take a look at it later today |
/// ``` | ||
/// | ||
/// This will result in a log file located at `/some/path/rotating.log`. | ||
pub fn mb_100( |
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.
Is there some significance to 100 MB log files and max of 9 back ups?? I ask because I think creating helpers for different values will be too cumbersome. I think in this case it makes more sense to just take in the size of log files and max backups desired.
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 just wanted to create at least one helper that will show an example on how to create a new appender\rotation.
If you think it's better to remove it I will remove it.
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 think making the helper more generic taht takes in a size parameter would be good enough to show how it works and is probably the only helper we would need.
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.
will change
tracing-appender/src/inner.rs
Outdated
let buf_len = buf.len(); | ||
self.refresh_writer(&buf_len); | ||
self.writer.write_all(buf).map(|_| buf_len) |
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.
This is fairly similar to what InnerRollingAppender
does except it encapsulates it with a method call.
It might make more sense to have a parent struct called InnerAppender
which wraps a trait called InnerAppenderTrait
(not sure of a good name, just a placeholder). I feel it'll also help in the future when/if new types of appenders may be needed.
Both InnerRotatingAppender
and InnerRollingAppender
can implement this trait.
pub(crate) trait InnerAppenderTrait {
record(&mut self, buf: &[u8]) -> Result<usize>;
refresh_writer(&mut self);
....
}
pub(crate) struct InnerAppender<T: InnerAppenderTrait> {
appender: T,
}
impl io::Write for InnerAppender<T: InnerAppenderTrait> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.appender.record(buf);
}
....
}
Maybe this is not ideomatic in rust and @hawkw feels differently.
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 will try to create something like that, but I a little unsure of how to work correctly with traits.
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.
done
rotation, | ||
}) | ||
} | ||
fn refresh_writer(&mut self, size: &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.
nit: A new line between methods could be added in a few places.
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.
will fix this.
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.
done
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.
This is some good progress. Still a few things to address concerning the major structures and then I'll look at the rest of the review.
use std::path::Path; | ||
|
||
pub(crate) trait InnerAppenderTrait<R>: io::Write |
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.
nit: Something better named would be nice as pub(crate) trait
already signifies this is a trait. Something like AppendInnder
?
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.
will rename
} | ||
impl<R, T: InnerAppenderTrait<R>> InnerAppenderWrapper<R, T> { |
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.
nit let's add a line break here.
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.
will fix
use std::path::Path; | ||
|
||
pub(crate) trait InnerAppenderTrait<R>: io::Write | ||
where | ||
Self: Sized, |
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 believe specifying this will prevent making the trait into an object
https://doc.rust-lang.org/std/marker/trait.Sized.html
I may be wrong though. I've never used Sized
before.
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 need it for Result
where | ||
Self: Sized, | ||
{ | ||
fn new(rotation: R, log_directory: &Path, log_filename_prefix: &Path) -> io::Result<Self>; |
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.
Tying the constructor to a trait method will make the code brittle.
The constructor should only be implemented by InnerAppenderWrapper
. InnerAppenderTrait
I think would be more appropriate for only specifying the contract for how logs are appended.
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 have to have this function since InnerAppenderWrapper
need it in order to create the appenders.
/// ``` | ||
/// | ||
/// This will result in a log file located at `/some/path/rotating.log`. | ||
pub fn mb_100( |
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 think making the helper more generic taht takes in a size parameter would be good enough to show how it works and is probably the only helper we would need.
impl io::Write for InnerRotatingAppender { | ||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { | ||
let buf_len = buf.len(); | ||
self.writer.write_all(buf).map(|_| buf_len) | ||
} | ||
|
||
fn flush(&mut self) -> io::Result<()> { | ||
self.writer.flush() | ||
} |
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.
We don't need to implement io::Write again for each appender impl. If you add a default method record
/write
then you can just call that from the impl of io::Write for InnerAppenderWrapper
and not have to duplicate code for every appender.
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 will still have to create these methods for each appender, I can't create a default method that will access the appenders buffers.
Ok so after reading your comments, and reviewing the code again I did notice the flaws of using a Trait here. so I thought to remove the entire trait, what do you think? |
I'll take a crack at it (can't until thursday). I feel like there's a cleaner approach here. |
I'd like to see this change as well... :) |
@zekisherif did you had the chance to look at it? |
Hi @CfirTsabari Thanks for the contribution and the time you spent working on it. However, I think that there might be a simpler solution and us asking you to write it through this PR would be draining and tiring for all parties. for that reason, we’ll close this PR. |
Motivation
Adding an appender with max size per log file and max number of log files.
Addressing #858
Solution
Adding an appender very similar to the
RollingFileAppender
,that will base the rotation on the size of the log file and the number of log files.