这里我们利用libevent监听centos系统上的login日志文件,文件路径:/var/log/secure。(ubuntu下是"/var/log/auth.log")
代码如下 test_file.cpp:
#include <iostream>
#include <thread>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <event2/event.h>
#include <event2/listener.h>
#include <event2/thread.h>
#define SPORT 5001
using namespace std;
void read_file(evutil_socket_t fd, short which, void* arg){
char buf[1024] = {0};
int len = read(fd, buf, sizeof(buf) - 1);
if(len > 0){
cout<<buf<<endl;
}else{
cout<<"."<<flush;
this_thread::sleep_for(chrono::seconds(1));
}
}
int main()
{
#ifdef _WIN32
//windows初始化socket库
WSADATA wsa;
WSAStartup(MAKEWORD(2, 2), &wsa);
#else
//发送数据给已关闭socket时,忽略管道信息.
//否则可能导致程序dump.
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
return -1;
}
#endif
event_config* conf = event_config_new();
//设置文件描述符
event_config_require_features(conf, EV_FEATURE_FDS);
event_base* base = event_base_new_with_config(conf);
event_config_free(conf);
if(!base){
cerr<<"event_base_new_with_config failed!"<<endl;
return -1;
}
//ubuntu下打开"/var/log/auth.log"
int sock = open("/var/log/secure", O_RDONLY|O_NONBLOCK, 0);
if(sock <= 0){
cerr<<"open /var/log/secure failed!"<<endl;
return -2;
}
//文件指针移到结尾处
lseek(sock, 0, SEEK_END);
//监听文件数据
event* fev = event_new(base, sock, EV_READ|EV_PERSIST, read_file, 0);
event_add(fev, NULL);
std::cout<<"............."<<std::endl;
event_base_dispatch(base);
event_base_free(base);
#ifdef _WIN32
//清理window的socket库
WSACleanup();
#endif
return 0;
}
在centos下的执行结果如下: