提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
工作中,经常遇到需要分析大量日志文件的情况,对日志文件的批量处理,并根据指定敏感词进行筛选、分析已经成为经常遇到的问题,此时需要小工具帮助我们快速分析。本小程序为C++代码编写,代码涉及字符串解析、批量处理文件、计数统计。
示例
代码如下(示例):
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <string.h>
#include <stdio.h>
#include <map>
#include <stdio.h>
#include <cstring>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <errno.h>
using namespace std;
void getFiles(std::string path, std::vector<std::string> &files);
long long SplitFile_free (const std::string& str)
{
std::size_t found = str.find_last_of(' ');
long long key = atoll(str.substr(found+1).c_str());
// std::cout << " key: " << key <<endl;
if (key == 0)
{
printf("illegal character!\n");
}
return key;
}
long long SplitFile_malloc (const std::string& str)
{
std::string::size_type nPos1 = std::string::npos;
std::string::size_type nPos2 = std::string::npos;
nPos1 = str.find_last_of(',');
nPos2 = str.find_last_of("addr ",nPos1-1);
string str_tmp;
if(nPos1 != -1 && nPos2 != -1)
{
str_tmp = str.substr(nPos2 + 1, nPos1 - nPos2 - 1);
}
long long key = atoll(str_tmp.c_str());
if (key == 0)
{
printf("illegal character!\n");
}
return key;
}
void getFiles(std::string path, std::vector<std::string> &files)
{
DIR *dir;
struct dirent *ptr;
if ((dir = opendir(path.c_str())) == NULL)
{
perror("Open dir error...");
exit(1);
}
/*
* 文件(8)、目录(4)、链接文件(10)
*/
while ((ptr = readdir(dir)) != NULL)
{
if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0)
continue;
else if (ptr->d_type == 8)
files.push_back(path + ptr->d_name);
else if (ptr->d_type == 10)
continue;
else if (ptr->d_type == 4)
{
//files.push_back(ptr->d_name);
getFiles(path + ptr->d_name + "/", files);
}
}
closedir(dir);
}
//void getFileName(char * dirPath)
//{
// DIR *dir=opendir(dirPath);
//
// if(dir==NULL)
// {
// printf("%s\n",strerror(errno));
// return;
// }
// chdir(dirPath);//进入到当前读取目录
// struct dirent *ent;
// while((ent=readdir(dir)) != NULL)
// {
// if(strcmp(ent->d_name,".")==0||strcmp(ent->d_name,"..")==0)
// {
// continue;
// }
// int size = strlen(ent->d_name);
// if(strcmp( ( ent->d_name + (size - 4) ) , ".log") != 0) //只存取.gmm 扩展名的文件名
// continue;
//
// struct stat st;
// stat(ent->d_name,&st);
// if(S_ISDIR(st.st_mode)) //如果是子目录,继续递归搜索
// {
// getFileName(ent->d_name);
// }
// else
// {
// printf("%s\n",ent->d_name);
//
// }
// }
// closedir(dir);
// chdir("..");//返回当前目录的上一级目录
//}
int main() {
// string filename = "/home/operation/wxx/myfile/111.log";
// getFileName("/home/operation/wxx/myfile/");
string file_path;
cout << "请输入文件所在路径:如:/home/operation/wxx/myfile/ "<<endl;
cin >>file_path;
ifstream ifs(file_path, ios::in);//这里就不加双引号
string path = "/home/operation/wxx/myfile/";
vector<string> vec;
getFiles(file_path, vec);
// string filename = "/home/operation/wxx/myfile/file/nemo-as-20220412.170.log";
map<long long int, string> m_malloc;
string line;
long long key;
int freeNum = 0; //文件中所有包含memchk free addr的行数
int mallocNum = 0; //文件中所有包含memchk malloc addr的行数
int matchNum = 0; //文件中free-malloc匹配的行数
int dismatchNum = 0; //文件中只有free未找到malloc的行数
int nomemchk = 0;//文件中不包含memchk free addr且不包含memchk malloc addr的行数
string keyword_malloc = "memchk malloc addr";
string keyword_free = "memchk free addr";
string::size_type idx_malloc;
string::size_type idx_free;
for(auto &s : vec)
{
printf("文件名是 %s\n",s.c_str());
fstream fin;
fin.open(s.c_str(), ios::in);
while (getline(fin, line))
{
//查找包含memchk malloc addr的字符串,截取地址,并存入vector中
idx_malloc = line.find(keyword_malloc);
//查找包含memchk free addr的字符串,截取地址
idx_free = line.find(keyword_free);
if(idx_malloc != string::npos)
{
key = SplitFile_malloc(line);
mallocNum++;
m_malloc.insert(pair<long long int, string>(key, ""));
}
else if(idx_free != string::npos)
{
key = SplitFile_free(line);
if(key != 0)
{
freeNum++;
}
//将此地址和vector中的key做对比,若找到此key,则删除;没找到,则pass不做处理
map<long long int, string>::iterator iter;
iter = m_malloc.find(key);
if(iter != m_malloc.end())
{
m_malloc.erase(iter);
matchNum++;
}
else
{
dismatchNum++;
}
}
else
{
nomemchk++;
// printf("%s\n",line.c_str());
}
}
}
int nSize = m_malloc.size(); //存储malloc的map的大小
for(auto it = m_malloc.begin();it != m_malloc.end();++it)
{
std::cout << "未释放内存地址 is:"<< it->first << std::endl;
}
printf("文件中所有包含memchk malloc addr的行数: %d\n",mallocNum);
printf("文件中所有包含memchk free addr的行数: %d\n",freeNum);
printf("文件中不包含memchk free addr且不包含memchk malloc addr的行数: %d\n",nomemchk);
printf("文件中free和malloc匹配个数 = %d\n",matchNum);
printf("文件中只free未malloc的个数 = %d\n",dismatchNum);
printf("文件中只malloc未free的个数 = %d\n",nSize);
return 0;
}
2.文件内容数据
数据如下(示例):
20220413181752|110102|ERROR|||2022-04-13 18:17:52.610|139823056570112||memchk malloc addr 139822196891360, size 24
20220413181752|110102|ERROR||1432513-30053|2022-04-13 18:17:52.610|139819539609344||memchk free addr 139822226983776
20220413181752|110102|ERROR||1431865-10276|2022-04-13 18:17:52.610|139821007742720||memchk free addr 139822343119072
20220413181752|110102|ERROR||1432513-30053|2022-04-13 18:17:52.610|139819539609344||memchk free addr 139822196890592
20220413181752|110102|ERROR||1430109-30053|2022-04-13 18:17:52.610|139821007742720||memchk malloc addr 139825628559280, size 232
2.执行程序并输出
总结
上述示例仅供参考,希望遇到多文件处理、字符串解析的时候可以派上用场。