您的位置:首页 > 编程语言 > C语言/C++

用C++实现读取windows日志并用zlib压缩后通过jwsmtp邮件发送出去.

2011-08-26 14:58 696 查看
情况是这样的, 我们的生活汇网站(http://www.shenghuo56.com)是放在一个windows服务器上的,因为该服务器上的网站比较多,应用程序池常常出错,出错后,会在windows的系统日志里有体现,所以,我打算写这样一个程序来监控windows的日志,如果发现有异常,就把日志发送到我指定的邮箱里,可以是一个139的邮箱,这样就可以做到短信提醒了。

我会在最后附上原码的,先说一下这个程序的功能。

过滤功能
1. 增量事件读取,只读取最后一次读取之后的日志
2. 可以按事件等级过滤,如error, warning, infomation等
3. 可以按来源进行过滤,如你可以指定只监控apache的日志
4. 可以指定读取[系统,应用,安全]类的日志

邮件发送功能
1. 可以配置smtp服务器
2. 只支持向一个邮箱发送邮件
3. 以附件的方式发送日志

压缩功能
1. 为了防止文件过大,把日志文件经过压缩后以邮件附件的方式发送出去。

运行方式
开发完成后,在系统中建立一个计划任务,自动运行本程序,完成采集发送功能。

主要程序片段说明,所有自己写的代码都在event_monitor.cpp中

发送邮件的功能

view plaincopy to clipboardprint?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来压缩文件的功能

view plaincopy to clipboardprint?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

源码及可执行文件
开发环境是Visual Studio 2008
源码
可执行文件
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: