使用c++读取日志统计pv uv
使用c++读取日志统计pv uv
在linux系统下通过c++读取日志文件,统计pv uv。
代码
main.cpp 文件如下, 执行下面命令编译
g++ -o sumary main.cpp
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <map>
/**
* 判断字符串 src 里面是否包含 dest
*/
bool string_contains(std::string & src, std::string dest){
std::size_t idx = src.find(dest);
if(idx != std::string::npos){
return true;
}else{
return false;
}
}
int main(int argc, char * argv[]){
std::cout << argc;
std::vector<std::string> vec;
if(argc > 1){
for(int i=1;i<argc;i++){
vec.push_back(argv[i]);
}
}
std::ifstream fin;
std::map<std::string, long> sumaryMap;
for(auto v:vec){
std::map<std::string, long> uniqMap;
//std::cout << "filename:" << v << std::endl;
fin.open(v);
std::string line;
long countHttp = 0;
while(std::getline(fin,line)){
if(!string_contains(line, "stat_http")){
continue;
}
std::string wdEnd = line.substr(line.find("_wd=")+4);
std::string wd = wdEnd.substr(0, wdEnd.find("&"));
//std::cout << wdEnd << std::endl;
//std::cout << wd << std::endl;
if(uniqMap.count(wd) == 0){
uniqMap.insert(std::pair<std::string,long>(wd, 1));
}else{
uniqMap[wd] = uniqMap[wd] + 1;
}
countHttp++;
// std::cout << line << std::endl;
}
sumaryMap.insert(std::pair<std::string,long>(v, countHttp));
fin.close();
/*
for(auto m:uniqMap){
std::cout << m.first << ":" << m.second << std::endl;
}
*/
std::cout << v << "\tuv:" << uniqMap.size() << std::endl;
}
for(auto m:sumaryMap){
std::cout << m.first << "\tpv:" << m.second << std::endl;
}
return 0;
}
日志文件按天存储,例如 data.log-20190621, data.log-20190622。
统计pv uv命令如下:
./sumary /data/log/data.log-201906*
代码思路
- 先将所有命令行参数中的文件保存到vector, 然后逐个日志文件处理
- 读取文件,过滤 包含 stat_http 的,如果一行中有 stat_http,说明是请求行
- 解析 _wd 参数的值,每个客户端的_wd参数是相同的,统计这个值就是uv