【原创】基于日志增量,统计qps,并基于ip排序
- 增量统计日志行数(只统计上一秒)
dns_qps.py
#!/usr/bin/env python
#_*_coding:utf-8_*_
import datetime
import re
import os
log_files = './dns_logs' #填写要分析的源日志
seek_files = './seek_log.tmp' #生成的临时文件,只用于保存位置seek信息,建议放/tmp/下
last_second = datetime.datetime.now() - datetime.timedelta(seconds=1) #取上一秒的时间,因为当前秒可能日志取不全
current_time = last_second.strftime('%d-%b-%Y %T') #时间格式根据日志格式做修改
#current_time = '17-Jun-2016 14:17:20'
if not os.path.exists(seek_files):
with open(seek_files, 'w+') as s:
s.write(str(0))
def write_file_end(log_files, seek_files):
with open(log_files, 'r') as f: #先找到log的最后字节位置
f.seek(0, 2) #seek(0)移动到文件起始、(0,2)移动到结尾
end_seek = f.tell()
with open(seek_files, 'w+') as s:
s.write(str(end_seek)) #把log的最后字节位置记录到seek文件
def get_count(log_files, begin):
count = 0
dns_pattern = re.compile(current_time+r'\.(\w+)(\s+)'+"queries: info: client") #这个正则要根据你的日志格式来,可以放到前边,声明一个变量,我这图省事了
with open(log_files, 'r') as f: #打开log,并移位到seek中记录的地方,从那开始读取行数并做累加,读完以后在更新seek文件到最新点
f.seek(begin)
for line in f.xreadlines():
if dns_pattern.match(line):
count += 1
print(count)
if __name__ == '__main__':
try:
with open(seek_files, 'r') as t:
if len(t.read()) == 0: #seek文件为空,强制begin=0,不为空,begin就等于seek
begin = 0
else:
t.seek(0)
begin = int(t.read())
with open(log_files, 'r') as f: #拿到end,end值为log文件的最后位置
f.seek(0, 2)
end = f.tell()
if end < begin: #因为日志定期会切分,切分后log的end将为0,此时begin强制为0,不然输出的count将为0
begin = 0
get_count(log_files, begin) #得到上一秒的总行数
write_file_end(log_files, seek_files) #把日志最后的位置保存给seek文件,用于下一秒的获取
except Exception, e:
print(0)
注意事项
把这个脚本放在zabbix之类的监控里,一秒执行一次,就可以算出每秒(其实是上一秒)增量部分的行数了,然后zabbix拿着这个度数绘图
# 运行脚本
/usr/bin/python2.6 dns_qps.py
下边更进一步,拿着这个增量,基于源ip,我们再做一个排序,把排序结果记录到一个log里
- 增量统计日志(tcpdump出来的数据)并排序,记录日志
dns_request_sort.py
#!/usr/bin/env python
#_*_coding:utf-8_*_
import datetime
import re
import os
import logging
import sys
master_dir = "/Data/logs/dns_qps/tcpdump_53" #把tcpdump的数据放这个目录里,原生的tcpdump数据
today = datetime.datetime.now().strftime('%Y%m%d')
log_files = os.path.join(master_dir, today+'.log'),
log_files = log_files[0]
if not os.path.exists(log_files):
sys.exit('Can not find logfile')
# for tcpdump
seek_files = '/tmp/seek_log_4_tcpdump_53.tmp' #同理存放seek信息的
last_second = datetime.datetime.now() - datetime.timedelta(seconds=1) #取上一秒的时间,因为当前秒可能日志取不全
current_time = last_second.strftime('%T')
#current_time = '16:54:17'
warning_num = 4 #设定阈值
warning_log = "/Data/logs/dns_qps/dns_warning_sort.log" #生成的排序ip的日志
def Mylogger(msg, logfile, level='info'):
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s [%(levelname)s] %(message)s',
filename=logfile,
filemode='a+')
if level == 'critical':
logging.critical(msg)
elif level == 'error':
logging.error(msg)
elif level == 'warn':
logging.warn(msg)
elif level == 'info':
logging.info(msg)
else:
logging.debug(msg)
if not os.path.exists(seek_files):
with open(seek_files, 'w+') as s:
s.write(str(0))
def write_file_end(log_files, seek_files):
with open(log_files, 'r') as f: #先找到log的最后字节位置
f.seek(0, 2)
end_seek = f.tell()
with open(seek_files, 'w+') as s:
s.write(str(end_seek)) #把log的最后字节位置记录到seek文件
def get_count(log_files, begin):
dns_pattern = re.compile(current_time+r'\.\d+ IP (\d+\.\d+\.\d+\.\d+)\.\d+[\s\S]*')
ip_list = []
with open(log_files, 'r') as f: #打开log,并移位到seek中记录的地方,从那开始读取行数并做累加,读完以后在更新seek文件到最新点
f.seek(begin)
for line in f.xreadlines():
if dns_pattern.match(line):
ip_list.append(dns_pattern.match(line).groups()[0]) #groups()[0]是匹配的ip字段
for item in set(ip_list): #最后得到一个大列表,里边放着一秒内的多个ip,可能有重叠,set()去重并循环它,每个item就是一个ip
if ip_list.count(item) >= warning_num: #列表中出现的ip的数量超过阈值就记录日志
Mylogger("%s %s 此IP: %s 访问达到 %d 次" % (today, current_time, item, ip_list.count(item)),
warning_log, level='warn')
if __name__ == '__main__':
try:
with open(seek_files, 'r') as t:
if len(t.read()) == 0:
begin = 0
else:
t.seek(0)
begin = int(t.read())
with open(log_files, 'r') as f:
f.seek(0, 2)
end = f.tell()
if end < begin: #因为日志定期会切分,切分后log的end将为0,此时begin强制为0,不然输出的count将为0
begin = 0
get_count(log_files, begin)
write_file_end(log_files, seek_files)
except Exception, e:
pass
最后附上跑tcpdump的那个脚本
本来想用python的pypcap来抓取数据包,然后用dpkt来分析的,但测了一下,抓出来的东西都是乱码,就放弃了,直接用shell调用tcpdump脚本了
while_53.sh
#!/usr/bin/env bash
master_dir="/Data/logs/dns_qps/tcpdump_53"
device="em1"
mkdir -p ${master_dir}
chown -R zabbix.zabbix ${master_dir}
sudo /bin/kill -9 `ps -ef|grep tcpdump|grep -v grep|awk '{print$2}'` 2>/dev/null
today=`date +%Y%m%d`
sudo /usr/sbin/tcpdump -i ${device} -nn udp port 53|grep "> 10.*\.53:" >> ${master_dir}/${today}.log &
把2个脚本放到crontab跑起来
00 00 * * * cd /Data/shell && sh while_53.sh #这个每天重启一次tcpdump用于按天分割日志
* * * * * cd /Data/shell && /usr/bin/python dns_request_sort.py #没那么敏感的要求,一分钟跑一次足矣
# 看下生成的日志
2016-08-26 16:20:01,568 [WARNING] 20160826 16:20:00 此IP: 10.1.0.110 访问达到 70 次
2016-08-26 16:21:01,616 [WARNING] 20160826 16:21:00 此IP: 10.1.0.110 访问达到 67 次
2016-08-26 16:22:01,665 [WARNING] 20160826 16:22:00 此IP: 10.1.0.110 访问达到 68 次
2016-08-26 16:23:01,714 [WARNING] 20160826 16:23:00 此IP: 10.1.0.110 访问达到 65 次
2016-08-26 16:24:01,766 [WARNING] 20160826 16:24:00 此IP: 10.1.20.253 访问达到 100 次
2016-08-26 16:24:01,766 [WARNING] 20160826 16:24:00 此IP: 10.1.0.110 访问达到 72 次
2016-08-26 16:25:01,815 [WARNING] 20160826 16:25:00 此IP: 10.1.0.110 访问达到 59 次
【原创】基于日志增量,统计qps,并基于ip排序的更多相关文章
- MySQL5.6主从复制搭建基于日志(binlog)
什么是MySQL主从复制 简单来说,就是保证主SQL(Master)和从SQL(Slave)的数据是一致性的,向Master插入数据后,Slave会自动从Master把修改的数据同步过来(有一定的延迟 ...
- (转)MySQL 主从复制搭建,基于日志(binlog
原文:http://blog.jobbole.com/110934/ 什么是MySQL主从复制 简单来说,就是保证主SQL(Master)和从SQL(Slave)的数据是一致性的,向Master插入数 ...
- Mysql5.7基于日志转为基于事务主从复制
将基于日志的复制变更为基于事务的复制 mysql版本要高于5.7.6 gtid_mode要设为off 处理步骤 详细步骤 1.查看主从mysql版本是否高于5.7.6 show variables l ...
- 基于日志数据分析以防御CC攻击的想法
1. What - 什么是CC攻击 CC攻击,即针对应用层HTTP协议的DDos攻击,攻击者在短时间内向目标服务器发送大量的HTTP请求,使得服务器会非常繁忙,资源消耗会增加:同时,如果请求中包含基于 ...
- Mysql5.7基于日志主从复制
主从同步概念 主从同步是异步复制 Mysql两种复制类型: 基于二进制日志 使用GTID完成基于事务的复制 基于日志三种方式: Mysql5.7需要注意的问题: 老版本方法创建mysql用户 #mys ...
- 基于短语的统计机器翻(PBMT) 开源工具 :Moses
如何运行Moses 1. Moses的历史 Moses是Pharaoh的升级版本,增加了许多功能.它是一个基于短语的统计机器翻译系统,整个系统用C++语言写成,从训练到解码完全开放源代码,可以运行在L ...
- R学习:《机器学习与数据科学基于R的统计学习方法》中文PDF+代码
当前,机器学习和数据科学都是很重要和热门的相关学科,需要深入地研究学习才能精通. <机器学习与数据科学基于R的统计学习方法>试图指导读者掌握如何完成涉及机器学习的数据科学项目.为数据科学家 ...
- 5-5配置Mysql复制 基于日志点的复制
配置MySQL复制 基于日志点的复制配置步骤 设置简单密码(可以选择不需要) set GLOBAL validate_password_length=6; set global validate_pa ...
- 基于机器学习的web异常检测——基于HMM的状态序列建模,将原始数据转化为状态机表示,然后求解概率判断异常与否
基于机器学习的web异常检测 from: https://jaq.alibaba.com/community/art/show?articleid=746 Web防火墙是信息安全的第一道防线.随着网络 ...
随机推荐
- C语言的傻瓜式随笔(一):嵌套循环-程序结构
循环语句的嵌套 一个循环结构内可以含有另一个循环,称为循环嵌套,又称多重循环.常用的循环嵌套是二重循环,外层循环称为外循环,内层循环称为内循环. ---------不知道哪来的基础概念 这是本宝宝的第 ...
- 资深人士剖析微软开源.NET事件:战略重心已经从PC转移到云端
本文是雷锋网对我的访谈整理的文章,源地址是 http://www.leiphone.com/news/201411/6KaGhD7PDABnvrRf.html 2014年11月13日,微软表示开源.N ...
- SQL Server 2000向SQL Server 2008 R2推送数据
[文章摘要]最近做的一个项目要获取存在于其他服务器的一些数据,为了安全起见,采用由其他“服务器”向我们服务器推送的方式实现.我们服务器使用的是SQL Server 2008 R2,其他“服务器”使用的 ...
- QParserGenerator的文法文件介绍
在沉默了数月之后,博主心血来潮想继续介绍QParserGenerator,在这里我们将不再继续介绍任何有关于LALR(1)的算法(那东西只会把你的脑子变成一团浆糊),让我们来看一下QParserGen ...
- 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC
系列文章 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC 七天学会ASP.NET MVC (二)——ASP.NET MVC 数据传递 七天学会ASP.NET MVC (三)— ...
- failed to load the jni shared library jvm
启动eclipse luna时候出现的, 原因在于,eclipse要求jdk是 32位的, 而我本机安装的是 64的!
- Objective-C 装饰模式--简单介绍和使用
装饰模式是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能.它是通过创建一个包装对象,也就是装饰来包裹真实的对象. 比如游戏机有一个GamePad类, 现在要增加一个作弊功能(例如100 ...
- Android笔记——数据库升级与降级
一.概述 SQLite是Android内置的一个很小的关系型数据库.SQLiteOpenHelper是一个用来辅助管理数据库创建和版本升级问题的抽象类.我们可以继承这个抽象类,实现它的一些方法来对数据 ...
- Java 对象引用方式 —— 强引用、软引用、弱引用和虚引用
Java中负责内存回收的是JVM.通过JVM回收内存,我们不需要像使用C语音开发那样操心内存的使用,但是正因为不用操心内存的时候,也会导致在内存回收方面存在不够灵活的问题.为了解决内存操作不灵活的问题 ...
- WPF入门教程系列十八——WPF中的数据绑定(四)
六.排序 如果想以特定的方式对数据进行排序,可以绑定到 CollectionViewSource,而不是直接绑定到 ObjectDataProvider.CollectionViewSource 则会 ...