-
Notifications
You must be signed in to change notification settings - Fork 382
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
[#5873] feat(gvfs-fuse): add debug log for FuseApiHandle #5905
base: main
Are you sure you want to change the base?
Conversation
9ae9ea0
to
3574bce
Compare
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.
Finally, we need to verify the log format to see if it meets expectations. This needs to be validated in the #5886, and you can wait for it to be merged.
inner: FuseApiHandle::new(fs, context), | ||
} | ||
} | ||
|
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.
These functions that are not part of the Filesystem trait do not need to add debug logs.
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.
new
is needed, we can use it to create a FuseApiHandleDebug
, and it will create a FuseApiHandle
as inner file system.
e.g.
let fs = DefaultRawFileSystem::new(gvfs);
FuseApiHandleDebug::new(fs, fs_context)
} | ||
|
||
impl<T: RawFileSystem> Filesystem for FuseApiHandleDebug<T> { | ||
async fn init(&self, req: Request) -> fuse3::Result<ReplyInit> { |
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 need to implement all interfaces of the Filesystem. If they are not implemented yet, an error log should be recorded.
async fn init(&self, req: Request) -> fuse3::Result<ReplyInit> { | ||
debug!("init: req: {:?}", req); | ||
let result = self.inner.init(req).await; | ||
debug!("init result: {:?}", result); |
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 an asynchronous multithreaded model. Logs from two print statements within a single function may be interleaved with logs from other interfaces. It is necessary to identify them in the logs.
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.
Okay, I use Request.unique
as the unique identifier of the request.
2024-12-28T12:23:01.966929Z DEBUG gvfs_fuse::fuse_api_handle: lookup [id=6]: error: Errno(2)
2024-12-28T12:23:01.967037Z DEBUG gvfs_fuse::fuse_api_handle: lookup [id=7]: req: Request { unique: 7, uid: 501, gid: 20, pid: 18890 }, parent: 1, name: "test_create"
2024-12-28T12:23:01.967056Z DEBUG gvfs_fuse::fuse_api_handle: lookup [id=7]: reply: ReplyEntry { ttl: 1s, attr: FileAttr { ino: 10001, size: 0, blocks: 0, atime: Timestamp { sec: 1735388581, nsec: 967051000 }, mtime: Timestamp { sec: 1735388581, nsec: 967051000 }, ctime: Timestamp { sec: 1735388581, nsec: 967051000 }, crtime: Timestamp { sec: 1735388581, nsec: 967051000 }, kind: RegularFile, perm: 420, nlink: 1, uid: 501, gid: 20, rdev: 0, flags: 0, blksize: 4096 }, generation: 0 }
async fn lookup(&self, req: Request, parent: Inode, name: &OsStr) -> fuse3::Result<ReplyEntry> { | ||
debug!("lookup: req: {:?}, parent: {:?}, name: {:?}", req, parent, name); | ||
let result = self.inner.lookup(req, parent, name).await; | ||
debug!("lookup result: {:?}", result); |
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.
If an error is returned, it should be logged using error!.
atime: Option<Timestamp>, | ||
mtime: Option<Timestamp>, | ||
) -> Result<FileStat, Errno> { | ||
debug!("get_modified_file_stat: file_id: {}, size: {:?}, atime: {:?}, mtime: {:?}", file_id, size, atime, mtime); |
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.
It’s best to convert file_id to a file path to improve readability, for example, "/a/b.txt(2342)". Other variables should follow a similar approach.
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.
implemented at a7073a0.
I use a wrapper struct TimestampDebug
which implement custom fmt::Display
trait,
now, Timestamp
will be displayed like:
mtime: Timestamp { sec: 1735386080, nsec: 26884000 }, ctime: Timestamp { sec: 1735386080, nsec: 26884000 }, crtime: Timestamp { sec: 1735386080, nsec: 26884000 }
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 implemented some methods like reply_attr_to_desc_str
, reply_entry_to_desc_str
to manually control the format.
Please refer to other PRs for the format of PR titles and descriptions. |
d1bfdba
to
425c490
Compare
close and reopen to run workflow |
@diqiu50 Please help review this PR, Thanks. |
"readdir [id={}]: req: {:?}, parent: {:?}, fh: {:?}, offset: {:?}", | ||
req.unique, req, parent, fh, offset | ||
); | ||
let result = self.inner.readdir(req, parent, fh, offset).await; |
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.
Need to show dir entries
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.
impl fmt::Display for TimestampDebug { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
let ts = &self.0; // Access the inner `Timestamp` | ||
write!(f, "{}.{:09}", ts.sec, ts.nsec) // Nanoseconds padded to 9 digits |
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 result of timestamp is not readable.
I think the TimestampDebug is not god for use. You can try to find a better solution.
At least you can use a function to convert it into a readable time format
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 implemented some methods like reply_attr_to_desc_str
, reply_entry_to_desc_str
to manually control the format.
|
||
pub(crate) struct FuseApiHandleDebug<T: RawFileSystem> { | ||
inner: FuseApiHandle<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.
separate this class as a new file
} | ||
Err(e) => { | ||
debug!("init [id={}]: error: {:?}", req.unique, e); | ||
Err(e) |
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 using error!
better?
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.
Yeah, error!
is better, fixed.
req.unique, | ||
FileAttrDebug { | ||
file_attr: &reply.attr | ||
} |
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.
Constructing an object is not as clear as using a function like to_desc_string()
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 implemented some methods like reply_attr_to_desc_str
, reply_entry_to_desc_str
to manually control the format.
let result = self.inner.read(req, inode, fh, offset, size).await; | ||
match result { | ||
Ok(reply) => { | ||
debug!("read [id={}]: reply: {:?}", req.unique, reply); |
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 result of is not clear enough.
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.
fixed.
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.
Overall, there is no issue. The readability of the logs needs to be improved and made more concise. Unimportant information can be ignored.
Implement a few methods for printing commonly used structures, without having to print them in the struct format
) -> fuse3::Result<ReplyDirectoryPlus<Self::DirEntryPlusStream<'a>>> { | ||
debug!( | ||
"readdirplus [id={}]: req: {:?}, parent: {:?}, fh: {:?}, offset: {:?}, lock_owner: {:?}", | ||
req.unique, req, parent, fh, offset, lock_owner |
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.
It would be better to print the filename as well.
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.
fixed.
1d9ff8a
to
d619db0
Compare
@unknowntpo All the code are merged to the main brach. you need to merge the pr to main |
@diqiu50 Okay, (I'm still working this PR) |
d4627de
to
ec48523
Compare
3defb39
to
136ec63
Compare
…o make log more readable
…n get_modified_file_stat
479e7be
to
87e01ff
Compare
Note that I use e.g.
|
@diqiu50 Done, please take a look. |
What changes were proposed in this pull request?
Implement
FuseApiHandleDebug
so we can log all input arguments and return values ofFuseApiHandle
.I use
tracing::debug
,tracing::error
with structure logging to format the message in key value pair format, so we don't need to control format manually.e.g.
Fix: #5873
Does this PR introduce any user-facing change?
No.
How was this patch tested?
tested with
fuse_test.rs
, along withMemoryFileSystem
.Now,
FuseApiHandleDebug
will wrapFuseApiHandle
and log all input arguments and returned values, if return value isResult
, we usematch
to extract and log the status of result, note that error will be logged if occured.To test this PR, run:
Here's some example logging generated by
test_fuse_system_with_auto
infuse_test.rs
: