有没有办法跟踪给定进程的所有文件 I/O?我真正需要的是从给定进程读取/写入的文件的位置(理想情况下,如果它是读取或写入操作,尽管这并不那么重要)。
我可以运行该流程并跟踪它,而不需要附加到现有流程,我认为这要简单得多。是否有任何类型的包装实用程序可以运行一个进程来监视文件访问?
lsof
:尝试作为初学者这样做:
lsof -p <PID>
此命令将列出具有传递的进程 ID 的进程的所有当前打开的文件、fd、套接字。
对于您的特殊需求,请查看我可以提供什么作为监控 php 脚本的解决方案:
php foo.php & _pid=$!
lsof -r1 -p $_pid
kill %1 # if you want to kill php script
strace
:我推荐使用
strace
。与 lsof
不同,只要进程正在运行,它就会保持运行。当系统调用被调用时,它会打印出正在调用哪些系统调用。 -e trace=file
仅过滤访问文件系统的系统调用:
sudo strace -f -t -e trace=file php foo.php
或者对于已经运行的进程:
sudo strace -f -t -e trace=file -p <PID>
除了 strace 之外,还有另一个选项,它不会显着减慢受监控的进程。使用Liunx内核的fanotify(不要与更流行的inotify混淆)可以监视整个挂载点的IO活动。通过非共享挂载命名空间,给定进程的挂载可以与系统的其余部分隔离(docker 背后的关键技术)。
这个概念的实现可以在我是作者的shournal中找到。
外壳上的示例:
$ shournal -e sh -c 'cat foo > bar'
$ shournal --query --history 1
...
1 written file(s):
/home/user/bar
1 read file(s):
/home/user/foo
strace 是一个很棒的工具,但它的输出有点冗长。
如果您愿意,可以使用我编写的一个工具,该工具可以处理 strace 输出,并提供包含以下数据的所有访问文件(也包括 TCP 套接字)的 CSV 报告:
1. 文件名
2. 读/写字节
3. 读/写操作次数
4. 文件被打开的次数
它可以在新进程或已经运行的进程上运行(使用/proc/fd数据)。
我发现它对于调试场景和性能分析很有用。
您可以在这里找到它:iotrace
输出示例:
Filename, Read bytes, Written bytes, Opened, Read op, Write op
/dev/pts/1,1,526512,0,1,8904
socket_127.0.0.1:47948->127.0.0.1:22,1781764,396,0,8905,11
myfile.txt,65,0,9,10,0
pipe:[3339],0,0,0,1,0
之后,您可以在Excel或其他工具中处理CSV数据,以进行排序或其他所需的分析。
缺点是您需要下载和编译,而且它并不总是 100% 准确。
这样的事情可能会减轻文件活动监控对性能的影响。
$ watch -n 2.0 timeout 0.2 strace -p `pgrep myprogram` -fe trace=file
其中
myprogram
是进程名称,2.0
是每个监控周期之间的空闲时间,0.2
是监控周期的长度(以秒为单位)。