一、inotify
     inotify是内核的一个特性,可以用来监控目录、文件的读写等事件,当监控目标是目录时,inotify除了会监控目录本身,还会监控目录中的文件。inotify的监控功能由如下的几个系统调用完成:inotify_init(2) (or inotify_init1(2)), inotify_add_watch(2), inotify_rm_watch(2), read(2), and close(2).
     inotify的主要操作基于inotify_init 返回的inotify文件描述符,该描述符的作用类似于epoll用到的epoll_fd。inotify在监控目录的时候,不支持对目录的递归监控,即只能监控一层目录,如果需要递归监控的,就需要将这些目录通过inotify_add_watch添加进来。
     inotify目前只能检测到目标文件(夹)发生了什么操作,无法检查出是哪个进程触发的这项操作。(注:fanotify函数接口支持获取触发操作的进程pid,但是fanotify支持的检测类型比inotify少太多,使用者也比较少)
     
     需求:监控/home/sxhlinux/test/test.txt的状态
     
  C语言实现:
#include <stdio.h>
#include <stdlib.h>
#include <sys/inotify.h>
#include <errno.h>
#include <string.h>
#include <sys/epoll.h>
 
int main(void)
{
    char *filename = "./log.txt";
 
    int inoti_fd = inotify_init1(IN_CLOEXEC);
    if (inoti_fd == -1) {
        printf("inotify_init failed, %s\n", strerror(errno));
        exit(-1);
    }
 
    int file_fd = inotify_add_watch(inoti_fd, filename, IN_ALL_EVENTS);
    if (file_fd == -1) {
        printf("inotify_add_watch failed, %s\n", strerror(errno));
        exit(-1);
    }
 
    int epoll_fd = epoll_create(5);
    if (epoll_fd == -1) {
        printf("epoll_create failed, %s\n", strerror(errno));
        goto end;
    }
 
    struct epoll_event ev, event[5];
 
    memset(&ev, 0, sizeof(ev));
    ev.events = EPOLLIN | EPOLLET;
    ev.data.fd = inoti_fd;
    if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, inoti_fd, &ev) == -1) {
        printf("epoll_ctl failed, %s\n", strerror(errno));
        goto end;
    }
 
    int buf_size = sizeof(struct inotify_event) + 64 * sizeof(char);
    struct inotify_event * instance = malloc(buf_size);
    memset(instance, 0, buf_size);
 
    int value = 0;
    while ((value = epoll_wait(epoll_fd, event, 5, -1)) != -1) {
        int i = 0;
        for (i = 0; i < value; i ++) {
            if (event[i].data.fd == inoti_fd) {
                if (read(inoti_fd, instance, buf_size) > 0)
                    printf("file_id is %d, event is %u, cookie is %u, name is %s\n",
                            instance->wd, instance->mask, instance->cookie, instance->name);
                else
                    printf("read inoti_fd failed, %s\n", strerror(errno));
            }
            else
                printf("unknown file_fd %d\n", event[i].data.fd);
        }
    }
 
end:
    inotify_rm_watch(inoti_fd, file_fd);
 
    return 0;
     Python实现:
#!/usr/bin/python
 
import logging
from inotify import adapters
 
_DEFAULT_LOG_FORMAT = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
 
_LOGGER = logging.getLogger(__name__)
 
def _configure_logging():
    _LOGGER.setLevel(logging.DEBUG)
    ch = logging.FileHandler('./record', 'a')
    formatter = logging.Formatter(_DEFAULT_LOG_FORMAT)
    ch.setFormatter(formatter)
    _LOGGER.addHandler(ch)
 
def _main():
    i = adapters.Inotify()
    i.add_watch('/var/lib/logrotate.status')
 
    for event in i.event_gen():
        if event:
            (header, type_names, watch_path, filename) = event
            print ("WD=(%d) MASK=(%d) COOKIE=(%d) LEN=(%d) MASK->NAMES=%s WATCH-PATH=[%s] FILENAME=[%s]",\
            header.wd, header.mask, header.cookie, header.len, type_names, watch_path.decode('utf-8'), filename.decode('utf-8'))
            _LOGGER.info("WD=(%d) MASK=(%d) COOKIE=(%d) LEN=(%d) MASK->NAMES=%s WATCH-PATH=[%s] FILENAME=[%s]",\
            header.wd, header.mask, header.cookie, header.len, type_names, watch_path.decode('utf-8'), filename.decode('utf-8'))
 
if __name__ == '__main__':
    _configure_logging()
    _main()
     shell命令(依赖inotify-tools软件包):
#监控log.txt发生的操作,并输出到record文件中,另外inotifywait命令的-r选项支持递归遍历
$ inotifywait -m log.txt -o record
 
#inotifywatch 命令则用于统计一段时间内,某个文件所发生操作的统计数据
#上述的两个命令的具体用法参照man手册
二、systemtap监控
     systemtap可以监控系统调用,我们使用stap带的一个监控inode的插件inodewatch.stp 来实现对文件的监控。
$ yum install systemtab -y
$ yum install kernel-debug-debuginfo     #stap监控系统调用需要
$ stap -ve 'probe begin { log("hello world") exit() }'     #测试stap是否安装成功
$ ls -i log.txt      #查看要监控文件的inode号 2360637
$ df -h      #查看log.txt所在的磁盘分区
$ cat /proc/partitions     #查看各个磁盘分区的major、minor号 8 2
$ stap /usr/share/doc/systemtap-1.6/examples/io/inodewatch.stp 0x8 0x2 2360637     #监控log.txt即(0x8 0x2 2360637)所进行的操作,同时会显示出执行操作的进程ID

  

文件读写监控(inotify, systemtap)的更多相关文章

  1. Linux 文件操作监控inotify功能及实现原理【转】

    转自:http://blog.chinaunix.net/uid-26585427-id-5012973.html 1. inotify主要功能 它是一个内核用于通知用户空间程序文件系统变化的机制. ...

  2. 使用pt-ioprofile监控数据库io文件读写情况

    我们在做IO密集型的应用程序的时候,比如MySQL数据库,通常系统的表现取决于workload的类型. 比如我们要调优,我们就必须非常清楚的知道数据的访问规律,收集到足够的数据,用来做调优的依据. 有 ...

  3. Linux下使用inotify实现对文件的监控

    项目中,要实现用户通过网页设置參数,后台接收数据然后写串口. 网页写数据到本地文件,使用inotify监控文件的IN_MODIFY事件.当文件被改动,然后触发写串口事件. 第一个程序只把要监控的文件增 ...

  4. IO异步,读写压缩文件,监控文件系统

    这节结尾IO,讲一下异步操作文件,读写压缩文件,监控文件系统这三个知识点. 异步操作文件:     说到异步,必然要了解的是async和await这两个关键字(异步详情点击基于任务的异步编程(Task ...

  5. Sersync实现触发式文件同步 替代inotify和rsync

    Sersync实现触发式文件同步 替代inotify和rsync Pyinotify是一个Python模块,用来监测文件系统的变化. Pyinotify依赖于Linux内核的功能—inotify(内核 ...

  6. python学习之文件读写,序列化(json,pickle,shelve)

    python基础 文件读写 凡是读写文件,所有格式类型都是字符串形式传输 只读模式(默认) r  f=open('a.txt','r')#文件不存在会报错 print(f.read())#获取到文件所 ...

  7. 【Win 10 应用开发】文件读写的三种方案

    本文老周就跟伙伴们探讨一下关于文件读写的方法.总得来说嘛,有三种方案可以用,而且每种方案都各有特色,也说不上哪种较好.反正你得记住老祖宗留给我们的大智慧——事无定法,灵活运用者为上. OK,咱们开始吧 ...

  8. c语言文件读写操作总结

    C语言文件读写操作总结 C语言文件操作 一.标准文件的读写 1.文件的打开 fopen() 文件的打开操作表示将给用户指定的文件在内存分配一个FILE结构区,并将该结构的指针返回给用户程序,以后用户程 ...

  9. ActionScript 3.0入门:Hello World、文件读写、数据存储(SharedObject)、与JS互调

    近期项目中可能要用到Flash存取数据,并与JS互调,所以就看了一下ActionScript 3.0,现把学习结果分享一下,希望对新手有帮助. 目录 ActionScript 3.0简介 Hello ...

随机推荐

  1. mysqlslap 使用总结

    mysqlslap 可以用于模拟服务器的负载,并输出计时信息.其被包含在 MySQL 5.1 的发行包中.测试时,可以指定并发连接数,可以指定 SQL 语句.如果没有指定 SQL 语句,mysqlsl ...

  2. iOS越狱包

    编译完了的程序是xxx.app文件夹,我们需要制作成ipa安装包,方便安装 找一个不大于500*500的png图片(程序icon图标即可),改名为:iTunesArtwork,注意不能有后缀名. 建立 ...

  3. CSS重设(reset)

    在当今网页设计/开发实践中,使用CSS来为语义化的(X)HTML标记添加样式风格是重要的关键.在设计师们的梦想中都存在着这样的一个完美世界:所有的浏览器都能够理解和适用多有CSS规则,并且呈现相同的视 ...

  4. UILabel自适应高度

    在网上看了一些,发现很多关于自适应高度的,不能用,就在下面写一种我常用的吧!保证可以直接粘贴复制到Xcode中运行. UILabel *label = [[UILabel alloc] init]; ...

  5. 用DMA直接驱动GPIO,实现GPIO最高输出速率(转)

    源:用DMA直接驱动GPIO,实现GPIO最高输出速率 先上图:STM32F303芯片,72M的主频 可以看到GPIO的达到了14.4M的翻转速率,      再来上代码: RCC_AHBPeriph ...

  6. onethink插件二(首页图片轮播)

    2014年8月1日 15:34:15 基于slice-box 写了一个图片轮播的插件. 一.功能: 1.图片轮播功能 2.自定义功能(数量,效果,打开方式) 3.多重效果一键切换 4.独立性强,不影响 ...

  7. backup-mysql.sh

    #!/bin/bash#auto backup mariadb#xuegod 2015-12-30#Define PATH 定义变量date=`date +%Y-%m-%d`BAKDIR=" ...

  8. DDD设计一个电商网站

    DDD设计一个电商网站(十一)-- 最后的准备    阅读目录 前言 准备 实现 结语 一.前言 最近实在太忙,上周停更了一周.按流程一步一步走到现在,到达了整个下单流程的最后一公里--结算页的处理. ...

  9. java_web学习(15)jQuery

    JavaScript 库作用及对比 为了简化 JavaScript 的开发, 一些 JavsScript 库诞生了. JavaScript 库封装了很多预定义的对象和实用函数.能帮助使用者建立有高难度 ...

  10. CSS3 :target伪类的理解与使用

    CSS3 :target伪类用来改变页面中锚链接URL所指向的ID元素的样式,例如你要改变描链接指向#tab的元素字体颜色为蓝色,哪么你可以这样写成#tab:target {color:blue} 浏 ...