• 增量统计日志行数(只统计上一秒)

dns_qps.py

  1. #!/usr/bin/env python
  2. #_*_coding:utf-8_*_
  3. import datetime
  4. import re
  5. import os
  6. log_files = './dns_logs' #填写要分析的源日志
  7. seek_files = './seek_log.tmp' #生成的临时文件,只用于保存位置seek信息,建议放/tmp/下
  8. last_second = datetime.datetime.now() - datetime.timedelta(seconds=1) #取上一秒的时间,因为当前秒可能日志取不全
  9. current_time = last_second.strftime('%d-%b-%Y %T') #时间格式根据日志格式做修改
  10. #current_time = '17-Jun-2016 14:17:20'
  11. if not os.path.exists(seek_files):
  12. with open(seek_files, 'w+') as s:
  13. s.write(str(0))
  14. def write_file_end(log_files, seek_files):
  15. with open(log_files, 'r') as f: #先找到log的最后字节位置
  16. f.seek(0, 2) #seek(0)移动到文件起始、(0,2)移动到结尾
  17. end_seek = f.tell()
  18. with open(seek_files, 'w+') as s:
  19. s.write(str(end_seek)) #把log的最后字节位置记录到seek文件
  20. def get_count(log_files, begin):
  21. count = 0
  22. dns_pattern = re.compile(current_time+r'\.(\w+)(\s+)'+"queries: info: client") #这个正则要根据你的日志格式来,可以放到前边,声明一个变量,我这图省事了
  23. with open(log_files, 'r') as f: #打开log,并移位到seek中记录的地方,从那开始读取行数并做累加,读完以后在更新seek文件到最新点
  24. f.seek(begin)
  25. for line in f.xreadlines():
  26. if dns_pattern.match(line):
  27. count += 1
  28. print(count)
  29. if __name__ == '__main__':
  30. try:
  31. with open(seek_files, 'r') as t:
  32. if len(t.read()) == 0: #seek文件为空,强制begin=0,不为空,begin就等于seek
  33. begin = 0
  34. else:
  35. t.seek(0)
  36. begin = int(t.read())
  37. with open(log_files, 'r') as f: #拿到end,end值为log文件的最后位置
  38. f.seek(0, 2)
  39. end = f.tell()
  40. if end < begin: #因为日志定期会切分,切分后log的end将为0,此时begin强制为0,不然输出的count将为0
  41. begin = 0
  42. get_count(log_files, begin) #得到上一秒的总行数
  43. write_file_end(log_files, seek_files) #把日志最后的位置保存给seek文件,用于下一秒的获取
  44. except Exception, e:
  45. print(0)

注意事项

把这个脚本放在zabbix之类的监控里,一秒执行一次,就可以算出每秒(其实是上一秒)增量部分的行数了,然后zabbix拿着这个度数绘图

  1. # 运行脚本
  2. /usr/bin/python2.6 dns_qps.py

下边更进一步,拿着这个增量,基于源ip,我们再做一个排序,把排序结果记录到一个log里

  • 增量统计日志(tcpdump出来的数据)并排序,记录日志

dns_request_sort.py

  1. #!/usr/bin/env python
  2. #_*_coding:utf-8_*_
  3. import datetime
  4. import re
  5. import os
  6. import logging
  7. import sys
  8. master_dir = "/Data/logs/dns_qps/tcpdump_53" #把tcpdump的数据放这个目录里,原生的tcpdump数据
  9. today = datetime.datetime.now().strftime('%Y%m%d')
  10. log_files = os.path.join(master_dir, today+'.log'),
  11. log_files = log_files[0]
  12. if not os.path.exists(log_files):
  13. sys.exit('Can not find logfile')
  14. # for tcpdump
  15. seek_files = '/tmp/seek_log_4_tcpdump_53.tmp' #同理存放seek信息的
  16. last_second = datetime.datetime.now() - datetime.timedelta(seconds=1) #取上一秒的时间,因为当前秒可能日志取不全
  17. current_time = last_second.strftime('%T')
  18. #current_time = '16:54:17'
  19. warning_num = 4 #设定阈值
  20. warning_log = "/Data/logs/dns_qps/dns_warning_sort.log" #生成的排序ip的日志
  21. def Mylogger(msg, logfile, level='info'):
  22. logging.basicConfig(
  23. level=logging.INFO,
  24. format='%(asctime)s [%(levelname)s] %(message)s',
  25. filename=logfile,
  26. filemode='a+')
  27. if level == 'critical':
  28. logging.critical(msg)
  29. elif level == 'error':
  30. logging.error(msg)
  31. elif level == 'warn':
  32. logging.warn(msg)
  33. elif level == 'info':
  34. logging.info(msg)
  35. else:
  36. logging.debug(msg)
  37. if not os.path.exists(seek_files):
  38. with open(seek_files, 'w+') as s:
  39. s.write(str(0))
  40. def write_file_end(log_files, seek_files):
  41. with open(log_files, 'r') as f: #先找到log的最后字节位置
  42. f.seek(0, 2)
  43. end_seek = f.tell()
  44. with open(seek_files, 'w+') as s:
  45. s.write(str(end_seek)) #把log的最后字节位置记录到seek文件
  46. def get_count(log_files, begin):
  47. dns_pattern = re.compile(current_time+r'\.\d+ IP (\d+\.\d+\.\d+\.\d+)\.\d+[\s\S]*')
  48. ip_list = []
  49. with open(log_files, 'r') as f: #打开log,并移位到seek中记录的地方,从那开始读取行数并做累加,读完以后在更新seek文件到最新点
  50. f.seek(begin)
  51. for line in f.xreadlines():
  52. if dns_pattern.match(line):
  53. ip_list.append(dns_pattern.match(line).groups()[0]) #groups()[0]是匹配的ip字段
  54. for item in set(ip_list): #最后得到一个大列表,里边放着一秒内的多个ip,可能有重叠,set()去重并循环它,每个item就是一个ip
  55. if ip_list.count(item) >= warning_num: #列表中出现的ip的数量超过阈值就记录日志
  56. Mylogger("%s %s 此IP: %s 访问达到 %d 次" % (today, current_time, item, ip_list.count(item)),
  57. warning_log, level='warn')
  58. if __name__ == '__main__':
  59. try:
  60. with open(seek_files, 'r') as t:
  61. if len(t.read()) == 0:
  62. begin = 0
  63. else:
  64. t.seek(0)
  65. begin = int(t.read())
  66. with open(log_files, 'r') as f:
  67. f.seek(0, 2)
  68. end = f.tell()
  69. if end < begin: #因为日志定期会切分,切分后log的end将为0,此时begin强制为0,不然输出的count将为0
  70. begin = 0
  71. get_count(log_files, begin)
  72. write_file_end(log_files, seek_files)
  73. except Exception, e:
  74. pass

最后附上跑tcpdump的那个脚本

本来想用python的pypcap来抓取数据包,然后用dpkt来分析的,但测了一下,抓出来的东西都是乱码,就放弃了,直接用shell调用tcpdump脚本了

while_53.sh

  1. #!/usr/bin/env bash
  2. master_dir="/Data/logs/dns_qps/tcpdump_53"
  3. device="em1"
  4. mkdir -p ${master_dir}
  5. chown -R zabbix.zabbix ${master_dir}
  6. sudo /bin/kill -9 `ps -ef|grep tcpdump|grep -v grep|awk '{print$2}'` 2>/dev/null
  7. today=`date +%Y%m%d`
  8. sudo /usr/sbin/tcpdump -i ${device} -nn udp port 53|grep "> 10.*\.53:" >> ${master_dir}/${today}.log &

把2个脚本放到crontab跑起来

  1. 00 00 * * * cd /Data/shell && sh while_53.sh #这个每天重启一次tcpdump用于按天分割日志
  2. * * * * * cd /Data/shell && /usr/bin/python dns_request_sort.py #没那么敏感的要求,一分钟跑一次足矣
  1. # 看下生成的日志
  2. 2016-08-26 16:20:01,568 [WARNING] 20160826 16:20:00 IP: 10.1.0.110 访问达到 70
  3. 2016-08-26 16:21:01,616 [WARNING] 20160826 16:21:00 IP: 10.1.0.110 访问达到 67
  4. 2016-08-26 16:22:01,665 [WARNING] 20160826 16:22:00 IP: 10.1.0.110 访问达到 68
  5. 2016-08-26 16:23:01,714 [WARNING] 20160826 16:23:00 IP: 10.1.0.110 访问达到 65
  6. 2016-08-26 16:24:01,766 [WARNING] 20160826 16:24:00 IP: 10.1.20.253 访问达到 100
  7. 2016-08-26 16:24:01,766 [WARNING] 20160826 16:24:00 IP: 10.1.0.110 访问达到 72
  8. 2016-08-26 16:25:01,815 [WARNING] 20160826 16:25:00 IP: 10.1.0.110 访问达到 59

【原创】基于日志增量,统计qps,并基于ip排序的更多相关文章

  1. MySQL5.6主从复制搭建基于日志(binlog)

    什么是MySQL主从复制 简单来说,就是保证主SQL(Master)和从SQL(Slave)的数据是一致性的,向Master插入数据后,Slave会自动从Master把修改的数据同步过来(有一定的延迟 ...

  2. (转)MySQL 主从复制搭建,基于日志(binlog

    原文:http://blog.jobbole.com/110934/ 什么是MySQL主从复制 简单来说,就是保证主SQL(Master)和从SQL(Slave)的数据是一致性的,向Master插入数 ...

  3. Mysql5.7基于日志转为基于事务主从复制

    将基于日志的复制变更为基于事务的复制 mysql版本要高于5.7.6 gtid_mode要设为off 处理步骤 详细步骤 1.查看主从mysql版本是否高于5.7.6 show variables l ...

  4. 基于日志数据分析以防御CC攻击的想法

    1. What - 什么是CC攻击 CC攻击,即针对应用层HTTP协议的DDos攻击,攻击者在短时间内向目标服务器发送大量的HTTP请求,使得服务器会非常繁忙,资源消耗会增加:同时,如果请求中包含基于 ...

  5. Mysql5.7基于日志主从复制

    主从同步概念 主从同步是异步复制 Mysql两种复制类型: 基于二进制日志 使用GTID完成基于事务的复制 基于日志三种方式: Mysql5.7需要注意的问题: 老版本方法创建mysql用户 #mys ...

  6. 基于短语的统计机器翻(PBMT) 开源工具 :Moses

    如何运行Moses 1. Moses的历史 Moses是Pharaoh的升级版本,增加了许多功能.它是一个基于短语的统计机器翻译系统,整个系统用C++语言写成,从训练到解码完全开放源代码,可以运行在L ...

  7. R学习:《机器学习与数据科学基于R的统计学习方法》中文PDF+代码

    当前,机器学习和数据科学都是很重要和热门的相关学科,需要深入地研究学习才能精通. <机器学习与数据科学基于R的统计学习方法>试图指导读者掌握如何完成涉及机器学习的数据科学项目.为数据科学家 ...

  8. 5-5配置Mysql复制 基于日志点的复制

    配置MySQL复制 基于日志点的复制配置步骤 设置简单密码(可以选择不需要) set GLOBAL validate_password_length=6; set global validate_pa ...

  9. 基于机器学习的web异常检测——基于HMM的状态序列建模,将原始数据转化为状态机表示,然后求解概率判断异常与否

    基于机器学习的web异常检测 from: https://jaq.alibaba.com/community/art/show?articleid=746 Web防火墙是信息安全的第一道防线.随着网络 ...

随机推荐

  1. C语言的傻瓜式随笔(一):嵌套循环-程序结构

    循环语句的嵌套 一个循环结构内可以含有另一个循环,称为循环嵌套,又称多重循环.常用的循环嵌套是二重循环,外层循环称为外循环,内层循环称为内循环. ---------不知道哪来的基础概念 这是本宝宝的第 ...

  2. 资深人士剖析微软开源.NET事件:战略重心已经从PC转移到云端

    本文是雷锋网对我的访谈整理的文章,源地址是 http://www.leiphone.com/news/201411/6KaGhD7PDABnvrRf.html 2014年11月13日,微软表示开源.N ...

  3. SQL Server 2000向SQL Server 2008 R2推送数据

    [文章摘要]最近做的一个项目要获取存在于其他服务器的一些数据,为了安全起见,采用由其他“服务器”向我们服务器推送的方式实现.我们服务器使用的是SQL Server 2008 R2,其他“服务器”使用的 ...

  4. QParserGenerator的文法文件介绍

    在沉默了数月之后,博主心血来潮想继续介绍QParserGenerator,在这里我们将不再继续介绍任何有关于LALR(1)的算法(那东西只会把你的脑子变成一团浆糊),让我们来看一下QParserGen ...

  5. 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC

    系列文章 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC 七天学会ASP.NET MVC (二)——ASP.NET MVC 数据传递 七天学会ASP.NET MVC (三)— ...

  6. failed to load the jni shared library jvm

    启动eclipse luna时候出现的, 原因在于,eclipse要求jdk是 32位的, 而我本机安装的是 64的!

  7. Objective-C 装饰模式--简单介绍和使用

    装饰模式是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能.它是通过创建一个包装对象,也就是装饰来包裹真实的对象. 比如游戏机有一个GamePad类, 现在要增加一个作弊功能(例如100 ...

  8. Android笔记——数据库升级与降级

    一.概述 SQLite是Android内置的一个很小的关系型数据库.SQLiteOpenHelper是一个用来辅助管理数据库创建和版本升级问题的抽象类.我们可以继承这个抽象类,实现它的一些方法来对数据 ...

  9. Java 对象引用方式 —— 强引用、软引用、弱引用和虚引用

    Java中负责内存回收的是JVM.通过JVM回收内存,我们不需要像使用C语音开发那样操心内存的使用,但是正因为不用操心内存的时候,也会导致在内存回收方面存在不够灵活的问题.为了解决内存操作不灵活的问题 ...

  10. WPF入门教程系列十八——WPF中的数据绑定(四)

    六.排序 如果想以特定的方式对数据进行排序,可以绑定到 CollectionViewSource,而不是直接绑定到 ObjectDataProvider.CollectionViewSource 则会 ...