用C++实现读取windows日志并用zlib压缩后通过jwsmtp邮件发送出去.
情况是这样的, 我们的生活汇网站(http://www.shenghuo56.com)是放在一个windows服务器上的,因为该服务器上的网站比较多,应用程序池常常出错,出错后,会在windows的系统日志里有体现,所以,我打算写这样一个程序来监控windows的日志,如果发现有异常,就把日志发送到我指定的邮箱里,可以是一个139的邮箱,这样就可以做到短信提醒了。
我会在最后附上原码的,先说一下这个程序的功能。
过滤功能 1. 增量事件读取,只读取最后一次读取之后的日志 2. 可以按事件等级过滤,如error, warning, infomation等 3. 可以按来源进行过滤,如你可以指定只监控apache的日志 4. 可以指定读取[系统,应用,安全]类的日志 邮件发送功能 1. 可以配置smtp服务器 2. 只支持向一个邮箱发送邮件 3. 以附件的方式发送日志 压缩功能 1. 为了防止文件过大,把日志文件经过压缩后以邮件附件的方式发送出去。 运行方式 开发完成后,在系统中建立一个计划任务,自动运行本程序,完成采集发送功能。
主要程序片段说明,所有自己写的代码都在event_monitor.cpp中
发送邮件的功能
- jwsmtp::mailer mail(g_mail_to, g_mail_from, "日志报告",
- "见附件", g_smtp_server,
- jwsmtp::mailer::SMTP_PORT, false);
- string zippath = g_current_path;
- zippath += "\\eventlog.zip";
- bool atst = mail.attach(zippath);
- // Use authentication
- mail.username(g_smtp_user);
- mail.password(g_smtp_password);
- mail.authtype(jwsmtp::mailer::PLAIN);
- //mail.send();
- mail.operator()();
- string mret = mail.response();
- if(mret.substr(0,3) != "250") {
- mret = "发送邮件失败,请检查配置:" + mret;
- write_log(mret.c_str());
- } else {
- char tmp[32] = {0};
- ultoa(g_max_event_time, tmp, 10);
- string ini_path = g_current_path;
- ini_path += "\\cfg.ini";
- WritePrivateProfileString("ReadStatus","last_time",tmp,ini_path.c_str());
- write_log("发送邮件成功");
- }
使用zlib来压缩文件的功能
- bool zip_file() {
- int err=0;
- int opt_compress_level=Z_DEFAULT_COMPRESSION;
- void* buf=NULL;
- int size_buf=0;
- size_buf = WRITEBUFFERSIZE;
- buf = (void*)malloc(size_buf);
- zipFile zf;
- int errclose;
- zlib_filefunc64_def ffunc;
- fill_win32_filefunc64A(&ffunc);
- string zippath = g_current_path;
- zippath += "\\eventlog.zip";
- zf = zipOpen2_64(zippath.c_str(),0,NULL,&ffunc);
- if (zf == NULL)
- {
- return false;
- }
- FILE * fin;
- int size_read;
- string att_path = g_current_path;
- att_path += "\\attache_lot.txt";
- const char* filenameinzip = att_path.c_str();
- const char *savefilenameinzip;
- zip_fileinfo zi;
- unsigned long crcFile=0;
- int zip64 = 0;
- zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour =
- zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0;
- zi.dosDate = 0;
- zi.internal_fa = 0;
- zi.external_fa = 0;
- filetime((char*)filenameinzip,&zi.tmz_date,&zi.dosDate);
- zip64 = isLargeFile(filenameinzip);
- savefilenameinzip = filenameinzip;
- while( savefilenameinzip[0] == '\\' || savefilenameinzip[0] == '/' )
- {
- savefilenameinzip++;
- }
- // 去掉路径
- const char *tmpptr;
- const char *lastslash = 0;
- for( tmpptr = savefilenameinzip; *tmpptr; tmpptr++)
- {
- if( *tmpptr == '\\' || *tmpptr == '/')
- {
- lastslash = tmpptr;
- }
- }
- if( lastslash != NULL )
- {
- savefilenameinzip = lastslash+1; // base filename follows last slash.
- }
- err = zipOpenNewFileInZip3_64(zf,savefilenameinzip,&zi,
- NULL,0,NULL,0,NULL /* comment*/,
- (opt_compress_level != 0) ? Z_DEFLATED : 0,
- opt_compress_level,0,
- /* -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, */
- -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
- NULL,crcFile, zip64);
- if (err != ZIP_OK) {
- printf("error in opening %s in zipfile\n",filenameinzip);
- } else {
- fin = fopen64(filenameinzip,"rb");
- if (fin==NULL)
- {
- err=ZIP_ERRNO;
- printf("error in opening %s for reading\n",filenameinzip);
- }
- }
- if (err == ZIP_OK)
- do
- {
- err = ZIP_OK;
- size_read = (int)fread(buf,1,size_buf,fin);
- if (size_read < size_buf)
- if (feof(fin)==0)
- {
- printf("error in reading %s\n",filenameinzip);
- err = ZIP_ERRNO;
- }
- if (size_read>0)
- {
- err = zipWriteInFileInZip (zf,buf,size_read);
- if (err<0)
- {
- printf("error in writing %s in the zipfile\n",
- filenameinzip);
- }
- }
- } while ((err == ZIP_OK) && (size_read>0));
- if (fin)
- fclose(fin);
- if (err<0)
- err=ZIP_ERRNO;
- else
- {
- err = zipCloseFileInZip(zf);
- if (err!=ZIP_OK)
- printf("error in closing %s in the zipfile\n",
- filenameinzip);
- }
- errclose = zipClose(zf,NULL);
- if (errclose != ZIP_OK)
- printf("error in closing %s\n", zippath.c_str());
- }
配置文件说明
[LogFilter] #Security-安全日志,Application-应用日志,System-系统日志,all-所有日志 Category=all #如果是所有来源,则写all Source=all #显示信息? Infomation=0 #显示错误? Error=1 #显示警告? Warning=1 #显示审核成功? Audit_Success=0 #显示审核失败 Audit_Failure=1 [SMTP] smtp_server=smtp.qq.com smtp_user=xxx@qq.com smtp_password=xxxx mail_from=xxx@qq.com mail_to=xxx@qq.com [ReadStatus] last_time=0
zlib我用的是我编译过后的dll,用的是最新的,大家可以自己去下载一个自己编译了进行替换就可以了。
使用说明
注意, 这个工具不能放在有中文目录下面,目录中也不能有空格.
具体的配置文明见cfg.ini
文件说明
\ --程序根目录
说明文件.txt --本文件
event_monitor.exe --主程序
zlibwapi.dll --压缩库
cfg.ini --配置文件
在程序运行后,还会有生成一些其它文件,不用管他.
转载请注明来自生活汇http://www.shenghuo56.com