通过Python脚本快速统计分析日志

从朋友那里拿到一个需求,根据日志分析统计并发情况,统计自定义时间段的用户流量,具体需求如下:

  1. 晒选某个时间点的数据:查找某天下午1:30到2:30这个时间段或者自己定义,看看到底有多少
  2. 同时筛选出两个项目标号的文档,统计和去重统计17/18
  3. babyhealth:[2016-05-03 19:21:23] INFO orderinfo:472 - v41/nbCode/getauth||1508031:17

上面第三行的内容就是日志的格式,简单分析了一下需求,shell脚本、Excel 分列筛选透视、Python都 可以解决,考虑到日志数量较大,通过 Excel 效率可能偏低,因此这里采用 Python 进行处理。

处理的主要思路是:

  • 对日志文件内容进行分解。每条日志的关键信息有日期(2016-05-03)、时间(19:21:23)、值(1508031)、块(17),应用正则对日志进行逐行的匹配,提取关键信息,放到数据库中
  • 在数据库中通过SQL语句进行统计

对于第一部分,代码如下:

#! /usr/bin/env python
# -*- coding: utf-8 -*-
import re
import sqlite3
#说明
print u''
print u'-----------------使用说明-----------------'
print u'将脚本放入日志所在目录,运行脚本,输入日志\n文件名(含扩展名),将在相同目录生成log.db\n数据库'
print u'------------------------------------------'
print u''
#读取日志文件、连接数据库
name = raw_input('Please input the log name:')
log_db = sqlite3.connect('./log.db')
cursor = log_db.cursor()
#建表
cursor.execute('DROP TABLE IF EXISTS log')
cursor.execute('CREATE TABLE log (front, log_date, log_time, log_path, value, level)')
#设定正则规则
data_re = re.compile(r'正则规则不放了,会和代码编辑器冲突',re.S|re.M)
#读取日志文件
log = open('./%s' %name)
index = 0
#进行转换
try:
    for line in log:
        found = data_re.findall(line)
        if found != None and len(found) != 0:
            index = index + 1
            cursor.execute('INSERT INTO log (front, log_date, log_time, log_path, value, level) VALUES (?,?,?,?,?,?)', (found[0][0], found[0][1], found[0][2], found[0][3], found[0][4], found[0][5]))
            if index == 100:
                log_db.commit()
                #print '100 records has been submitted.'
    log_db.commit()
    print 'job done!'
    input()
except:
    pass

以上程序在 Linux 和 Windows 下都可以执行,生成 log.db 数据库, Linux 下可以直接使用 Sqlite3 对数据库进行操作, Windows 下可以安装 SQLite Expert 进行操作和查询,查询语句如下:

SELECT COUNT(*) FROM log WHERE log_date = '2016-05-03' and log_time between '13:30:00' and '14:30:00';
SELECT COUNT(*) FROM log WHERE log_date = '2016-05-03' and log_time between '13:30:00' and '14:30:00' and level = '17';
SELECT COUNT(*) FROM log WHERE log_date = '2016-05-03' and log_time between '13:30:00' and '14:30:00' and level = '18';
SELECT COUNT(DISTINCT value)FROM log WHERE log_date = '2016-05-03' and log_time between '13:30:00' and '14:30:00';
SELECT COUNT(DISTINCT value) FROM log WHERE log_date = '2016-05-03' and log_time between '13:30:00' and '14:30:00' and level = '17';
SELECT COUNT(DISTINCT value) FROM log WHERE log_date = '2016-05-03' and log_time between '13:30:00' and '14:30:00' and level = '18';

为了提高方便程度,可以用 Python 操作 SQLite3 进行查询:

#! /usr/bin/env python
# -*- coding: utf-8 -*-
import sqlite3

date = raw_input('Please input the date(eg.2016-05-03):')
start_time = raw_input('Please input the start time(eg.08:30:00):')
end_time = raw_input('Please input the end time(eg.09:30:00):')
stat_db = sqlite3.connect('./log.db')
cursor = stat_db.cursor()
cursor.execute('SELECT COUNT(*) FROM log WHERE log_date = \'%s\' and log_time between \'%s\' and \'%s\'' %(date,start_time,end_time))
amount_all = cursor.fetchall()[0][0]
cursor.execute('SELECT COUNT(DISTINCT value) FROM log WHERE log_date = \'%s\' and log_time between \'%s\' and \'%s\'' %(date,start_time,end_time))
amount_na = cursor.fetchall()[0][0]
cursor.execute('SELECT COUNT(*)  FROM log WHERE log_date = \'%s\' and log_time between \'%s\' and \'%s\' and level = \'17\'' %(date,start_time,end_time))
month_all = cursor.fetchall()[0][0]
cursor.execute('SELECT COUNT(DISTINCT value) FROM log WHERE log_date = \'%s\' and log_time between \'%s\' and \'%s\' and level = \'17\'' %(date,start_time,end_time))
month_na = cursor.fetchall()[0][0]
cursor.execute('SELECT COUNT(*) FROM log WHERE log_date = \'%s\' and log_time between \'%s\' and \'%s\' and level = \'18\'' %(date,start_time,end_time))
year_all = cursor.fetchall()[0][0]
cursor.execute('SELECT COUNT(DISTINCT value)  FROM log WHERE log_date = \'%s\' and log_time between \'%s\' and \'%s\' and level = \'18\'' %(date,start_time,end_time))
year_na = cursor.fetchall()[0][0]
print(u'')
print(u'------------统计------------')
print(u'%s %s~%s\n----------------------------\n总点击次数/人:%s|%s\n年用户:%s|%s\n月用户:%s|%s' % (date, start_time, end_time, amount_all, amount_na, year_all, year_na, month_all, month_na))
print(u'')
input('Press any key to exit...')

以上程序均基于 Python 2.7+ 环境。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,826评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,968评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,234评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,562评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,611评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,482评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,271评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,166评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,608评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,814评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,926评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,644评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,249评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,866评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,991评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,063评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,871评论 2 354

推荐阅读更多精彩内容