webtail——文件监控

简介: 文件监控直接通过了linux的inotify接口实现。这里没有考虑移植性,也就没像tailf那样,通过宏来判断是否支持inotify,如果不支持,降级使用循环轮寻的方式读取。 inotify的使用还是比较方便的基本上就是:inotify_init,inotify_add_watch,然后配合rea

文件监控直接通过了linux的inotify接口实现。这里没有考虑移植性,也就没像tailf那样,通过宏来判断是否支持inotify,如果不支持,降级使用循环轮寻的方式读取。

inotify的使用还是比较方便的基本上就是:inotify_init,inotify_add_watch,然后配合read系统调用,获取文件修改信息。因此实现也非常方便。

首先是在构造函数里面初始化inotify:
[cce lang=”cpp”]
inotifyFd = inotify_init();
[/cce]

然后提供一个watch接口,通过传入前文描述的TFile对象和内容读取的回调函数,添加对应文件的监控和回调。
[cce lang=”cpp”]
void FileWatcher::watch ( boost::shared_ptr< TFile > tFile, std::list< FileWatcher::ReadCallBack > callBackList )
{
if(!tFile->hasError() && !callBackList.empty()) {
int wd = inotify_add_watch(inotifyFd, tFile->name().c_str(), IN_MODIFY);
if(wd > 0) {
tFileMap.insert(std::make_pair<int, boost::shared_ptr<TFile> >(wd, tFile));
callBackMap.insert(std::make_pair<int, std::list<ReadCallBack> >(wd, callBackList));

//init read
std::string initContent = tFile->read();
BOOST_FOREACH(ReadCallBack &callback, callBackList) {
callback(initContent);
}
}
}
}
[/cce]
这里通过TFile的文件名,向内核注册添加该文件的modify事件,并且在注册成功之后,进行初始读取(这里有个小问题,由于后面websocket端没有做缓存,所以由于初始读取的时候还没有任何websocket客户端连接,所以通过web无法读取初始内容,也就是文件最后10行)。同时,这个类维护两个hashmap,分别是监听描述符wd->tFile和wd->callbacklist。

监听完成后,就是启动监听,也就是通过读取fd,感知被监听文件的变更,由于这里只监听了文件修改,那么读取到这个事件之后,就可以对该文件进行增量读取(前文已经描述了读取方法)。
[cce lang=”cpp”]
char * buffer = new char[inotifyBufferSize];
while(!_interrupted) {
if(read(inotifyFd, buffer, inotifyBufferSize) < 0) {
if(errno == EINTR) {
// interrupt
delete buffer;
return;
}
}
struct inotify_event *event = ( struct inotify_event * ) buffer;
int wd = event->wd;
BOOST_AUTO(tFileIter, tFileMap.find(wd));
if(tFileIter != tFileMap.end()) {
boost::shared_ptr<TFile> tFile = tFileIter->second;
std::string content = tFile->read();
BOOST_AUTO(iter, callBackMap.find(wd));
if(iter != callBackMap.end()) {
std::list<ReadCallBack> callbacks = iter->second;
BOOST_FOREACH(ReadCallBack &callback, callbacks) {
callback(content);
}
}
}
}
delete buffer;
[/cce]
这里参照inotify的文档,首先读取缓冲区大小设置为
[cce lang=”cpp”]
static const int inotifyBufferSize = sizeof(struct inotify_event) + NAME_MAX + 1;
[/cce]
也就是inotify_event结构的长度,和名字最大值。由于inotify_event是变长字段(包含一个可选的文件名字段),所以这里采用了系统限制的文件名最大值NAME_MAX,这个宏在climits中定义,在linux中大小为255字节。
然后通过系统调用read,读取文件描述符inotifyFd,这里如果没有新的事件产生,read会进入阻塞状态,节省系统资源。如果有返回,则处理返回的inotify_event对象(注意在监听modify事件的时候,是没有文件名的)。通过结构中的wd,从之前保存的hashmap中获取对应的tFile对象进行增量读取,然后再读取wd对应的回调函数,将读取内容返回。
这里有个小问题需要处理,就是如何中断读取。之前为了在gtest中能够通过单元测试的方式进行测试,通过查看手册可以知道,如果read调用被系统信号中断,会标记错误码为EINTR。所以,当读取失败的时候,可以通过对ERRNO检查,判断是否是信号中断。

由于程序会一直运行,知道通过信号终止,所以析构变的不是很重要了。这里析构函数里面通过调用inotify_rm_watch将之前保存的wd全部去掉,然后通过close调用交inotify的文件描述符关闭即可:
[cce lang=”cpp”]
FileWatcher::~FileWatcher()
{
if(inotifyFd > 0) {
boost::unordered::unordered_map<int, boost::shared_ptr<TFile> >::iterator iter;
for(iter = tFileMap.begin(); iter != tFileMap.end(); ++iter) {
inotify_rm_watch(inotifyFd, iter->first);
}

close(inotifyFd);
}
}
[/cce]


转载自:https://coolex.info/blog/406.html

目录
相关文章
|
弹性计算 运维 监控
ecs实例性能监控
ecs实例性能监控
254 2
|
缓存 Ubuntu 安全
Ubuntu部署和体验Nexus3
在局域网部署了Nexus之后,可以缓存中央仓库的jar,开发的二方库发布到Nexus上,局域网内的其他人也可以从Nexus下载这些二方库使用,本文就来实战快速部署和验证docker下的nexus3搭建
967 0
Ubuntu部署和体验Nexus3
|
4天前
|
人工智能 NoSQL 前端开发
Chap03. SpringAI
SpringAI整合主流大模型,支持多模态、函数调用与RAG,提供统一API简化开发。通过ChatClient封装对话流程,结合Prompt工程、工具调用和知识库扩展,可快速构建智能客服、聊天机器人等应用,助力Java开发者高效集成AI能力。
|
9月前
|
NoSQL MongoDB 微服务
微服务——MongoDB常用命令——文档的分页查询
本文介绍了文档分页查询的相关内容,包括统计查询、分页列表查询和排序查询。统计查询使用 `count()` 方法获取记录总数或按条件统计;分页查询通过 `limit()` 和 `skip()` 方法实现,控制返回和跳过的数据量;排序查询利用 `sort()` 方法,按指定字段升序(1)或降序(-1)排列。同时提示,`skip()`、`limit()` 和 `sort()` 的执行顺序与编写顺序无关,优先级为 `sort()` &gt; `skip()` &gt; `limit()`。
338 1
|
8月前
|
机器学习/深度学习 存储 算法
18个常用的强化学习算法整理:从基础方法到高级模型的理论技术与代码实现
本文系统讲解从基本强化学习方法到高级技术(如PPO、A3C、PlaNet等)的实现原理与编码过程,旨在通过理论结合代码的方式,构建对强化学习算法的全面理解。
2100 10
18个常用的强化学习算法整理:从基础方法到高级模型的理论技术与代码实现
|
监控 druid Java
Druid【SpringBoot集成】监控数据库报错 Failed to bind properties under ‘‘ to javax.sql.DataSource 解决(含配置源码)
Druid【SpringBoot集成】监控数据库报错 Failed to bind properties under ‘‘ to javax.sql.DataSource 解决(含配置源码)
1148 0
日志框架log4j打印异常堆栈信息携带traceId,方便接口异常排查
日常项目运行日志,异常栈打印是不带traceId,导致排查问题查找异常栈很麻烦。
|
JSON 前端开发 算法
vite打包优化vite-plugin-compression的使用
【8月更文挑战第4天】vite打包优化vite-plugin-compression的使用
1649 4
|
存储 应用服务中间件 nginx
saltstack配置
SaltStack是一种新的基础设施管理方法开发软件,简单易部署,可伸缩的足以管理成千上万的服务器,和足够快的速度控制,与他们交流,以毫秒为单位。SaltStack提供了一个动态基础设施通信总线用于编排,远程执行、配置管理等等。
436 0
|
应用服务中间件 网络安全 数据安全/隐私保护
SSL证书在IIS上部署使用
该文介绍了如何在IIS上部署SSL证书以实现HTTPS访问。首先建议使用nginx,但若需使用IIS,需有SSL证书(fullchain.pem和privkey.pem)并熟悉IIS操作。文中提供了两种证书转换方法:已有openssl,使用命令`openssl pkcs12 -export`生成.pfx文件;无openssl,通过Python脚本(pyOpenSSL v23.2.0)转换。转换后的.pfx文件导入Windows,选择“本地用户”并输入密码。最后在IIS中绑定证书,测试https访问应能正常工作。
948 0