用Python和Awk进行日志分析


=Start=

缘由:

之前就做过网站访问日志的分析,分别用的是awk和Python,但都比较简单,只是简单选取了IP的维度,还没有区分访问的日期,这样的话如果某个IP在某一天中的访问次数很多,但在其它这一月/年终的其他时候访问次数不多,那在单纯只考虑IP访问次数的情况下是很难确定这样的IP的(而这样的IP又很有可能是爬虫或是攻击者的IP),因此需要加上时间维度,但如果时间维度做的太细,消耗时间太长;如果做的太粗又不容易发现问题;所以,这种情况下需要根据具体情况 & 实际需要来选取粒度。因为我这主要是各人分析用,所以可以使用简单的“以天为单位”来分析,用到了Python和awk进行日志处理,快速方便:

默认的Nginx记录日志的格式为(默认情况下以“空格”为分隔符,但在真实情况下是不利于日志分析的,但这里为了方便起见还是以默认的为示例进行说明):

#log format
log_format access '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $http_x_forwarded_for';

从日志中取一些样本进行查看:

# head -3 access.log
120.204.200.21 - - [25/Apr/2015:00:01:04 +0800] "GET /blog/ HTTP/1.1" 200 9082 "-" "DNSPod-Monitor/2.0" -
50.116.30.23 - - [25/Apr/2015:00:01:05 +0800] "GET /blog/feed HTTP/1.1" 304 0 "-" "Superfeedr bot/2.0 http://superfeedr.com - Make your feeds realtime: get in touch - feed-id:128926078" -
209.15.21.92 - - [25/Apr/2015:00:01:26 +0800] "HEAD /blog/ HTTP/1.1" 200 0 "-" "-" -

先用awk取几列看看:

$ cat access.log | awk '$3="-" {print substr($4, 2, 11),$1}'
$ cat access.log | awk '$3=="-" {print substr($4, 2, 11),$1}'

用awk对日志进行处理(根据“日期+IP”进行去重):

$ awk '{dict[substr($4, 2, 11)"\t"$1]++}; END{for(item in dict) print item"\t"dict[item]}' access.log

对大公司来说,日志是会按时间段进行切割的(这个几乎是必然的,否则访问日志过大的话容易引起各种问题/隐患),并用处理大数据的方法对日志进行处理(其实这几句话都是废话,我的真实目的是想引出HDFS和简单的Streaming)……

正文:

废话不多说,通过awk对日志进行处理了之后,记录的文件内容格式为:

date IP count

然后通过对处理后的文件再进行分析从而得到我们想要的各种结果:

  • #某一天的IP访问总量(PV)
  • #某一天的独立IP访问总量(UV)
  • #总IP访问量的排序(按IP访问量取top)
  • #某一指定IP在每/某一天的访问量(对IP进行去重计数)
  • …待添加…

这里需要用到二维数组的知识(如果需要增加更多的分析维度,那就需要多维数组了),但Python里面的二维数组用的少(貌似主要是做科研的用 NumPy 库和一些其他的专用库),去stackoverflow上搜了一堆感觉那种二维数组不是我想要的:

搜索关键字:
  • python 二维数组
  • python two dimensional array
  • python create dynamic two dimensional array
参考链接:

==

之前写另外一个东西的时候用了嵌套的dict代替二维数组(list),挺好用的,这次就依葫芦画瓢,整了个类似的:

#!/usr/bin/env python
# coding=utf-8
import sys, re

date_ip_x = {}
pv_of_date = {}
uv_of_date = {}
for line in sys.stdin:
    line = line.strip()
    res = re.split(" ", line)
    ip = res[0].strip()
    date = res[3].strip()[1:12]

    if date in date_ip_x:
        if ip in date_ip_x[date]:
            date_ip_x[date][ip] += 1
        else:
            date_ip_x[date][ip] = 1
    else:
        date_ip_x[date] = {ip:1}

for date in date_ip_x:
    pv_of_date[date] = len(date_ip_x[date])
#pv_of_date = {date:len(date_ip_x[date]) for date in date_ip_x}

for date in date_ip_x:
    uv_of_date[date] = 0
    for ip in date_ip_x[date]:
        uv_of_date[date] += date_ip_x[date][ip]

print date_ip_x
print pv_of_date
print uv_of_date

with open("date_ip_count.txt", 'w') as f:
    for date in date_ip_x:
        f.write('%s\n' % date)
        for ip in date_ip_x[date]:
            f.write('%s\t%d\n' % (ip, date_ip_x[date][ip]))
        f.write('\n')

with open("date_pv_uv.txt", 'w') as f:
    f.write('\n####PV_of_date####\n')
    for date in pv_of_date:
        f.write('%s\t%d\n' % (date, pv_of_date[date]))
    f.write('\n####UV_of_date####\n')
    for date in uv_of_date:
        f.write('%s\t%d\n' % (date, uv_of_date[date]))

根据以上的几个步骤处理了之后,就可以得到我们想要的数据了~~

参考链接:

=END=

, , ,

《 “用Python和Awk进行日志分析” 》 有 6 条评论

  1. 关于用户画像那些事,看这一文章就够了
    https://mp.weixin.qq.com/s/cHinmVC5o9DApFcI5odxNQ
    `
    用户画像的含义
    用户画像的作用
    用户画像的内容
    用户画像的生产
    用户特征的提取即用户画像的生产过程,大致可以分为以下几步:
      1. 用户建模,指确定提取的用户特征维度,和需要使用到的数据源。
      2. 数据收集,通过数据收集工具,如Flume或自己写的脚本程序,把需要使用的数据统一存放到Hadoop集群。
      3. 数据清理,数据清理的过程通常位于Hadoop集群,也有可能与数据收集同时进行,这一步的主要工作,是把收集到各种来源、杂乱无章的数据进行字段提取,得到关注的目标特征。
      4. 模型训练,有些特征可能无法直接从数据清理得到,比如用户感兴趣的内容或用户的消费水平,那么可以通过收集到的已知特征进行学习和预测。
      5. 属性预测,利用训练得到的模型和用户的已知特征,预测用户的未知特征。
      6. 数据合并,把用户通过各种数据源提取的特征进行合并,并给出一定的可信度。
      7. 数据分发,对于合并后的结果数据,分发到精准营销、个性化推荐、CRM等各个平台,提供数据支持。
    `

  2. MySQL日志安全分析技巧
    https://mp.weixin.qq.com/s?__biz=MzA3NzE2MjgwMg==&mid=2448904152&idx=1&sn=1d3c78c678ee7106d4f2a0dd627de903
    `
    常见的数据库攻击包括弱口令、SQL注入、提升权限、窃取备份等。对数据库日志进行分析,可以发现攻击行为,进一步还原攻击场景及追溯攻击源。

    0x01 Mysql日志分析
    general query log能记录成功连接和每次执行的查询,我们可以将它用作安全布防的一部分,为故障分析或黑客事件后的调查提供依据。

    1、查看log配置信息
    show variables like ‘%general%’;
    2、开启日志
    SET GLOBAL general_log = ‘On’;
    3、指定日志文件路径
    SET GLOBAL general_log_file = ‘/var/lib/mysql/mysql.log’;

    0x02 登录成功/失败
    不同的数据库连接工具,它在连接数据库初始化的过程中是不同的。通过这样的差别,我们可以简单判断出用户是通过连接数据库的方式。

    另外,不管你是爆破工具、Navicat for MySQL、还是命令行,登录失败都是一样的记录。

    在日志分析中,特别需要注意一些敏感的操作行为,比如删表、备库,读写文件等。
    关键词:drop table、drop function、lock tables、unlock tables、load_file() 、into outfile、into dumpfile。
    敏感数据库表:SELECT * from mysql.user、SELECT * from mysql.func

    0x03 SQL注入入侵痕迹
    检查方法:

    1、检查网站目录下,是否存在一些木马文件:
    2、检查是否有UDF提权、MOF提权痕迹
    检查目录是否有异常文件
    mysql\lib\plugin
    c:/windows/system32/wbem/mof/
    检查函数是否删除
    select * from mysql.func
    3、结合web日志分析。
    `

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注