原文:https://www.cnblogs.com/i-honey/p/7791564.html

在企业中,从日志中提取数据进行分析,可以帮助企业更加了解用户行为,用户最感兴趣的产品或者内容,分析得到数据后,可以决定企业在今后的走向。

从这些日志数据中,比较重要的有:

1. 用户访问最多的url,即用户在企业网站最感兴趣的产品或者内容

2. 用户群体的的主要线路是什么?移动?联通?电信?

3. 用户访问的高峰期是什么时候?最高PV(访问量)、UV(独立访客)、IP(独立IP)。

4. 各时段状态码数。比如304,表示静态资源在没有发生改变时,服务器要求客户使用了浏览器本地的缓存,可以降低服务器流量负载等。403、404如果异常得出现很多,则要根据访问得url来判断是否有恶意用户在对网站目录进行扫描和探测。400、500等状态码很多的情况就需要运维人员及时分析并排查原因。

5. 客户浏览器的名称、版本。统计出各种浏览器的分布情况,比如:如果手机浏览器、IE 6.0版本浏览器访问记录很多,则大概可以判断出用户群体大概的操作系统是winXP,win7以上版本,或是手机访问。那就需要考虑是否要对特定版本浏览器进行页面优化,或者如果客户是手机浏览器,那是否要压缩网站页面大小,降低流量消耗,亦或是否要对手机端优化,提升用户体验,牢牢得抓住客户。。

这里涉及部分SEO方面知识,仅作了解即可,如果企业真正需要了,再深入学习。

下面的例子对访问状态码和浏览器名称、版本进行了统计,以引出日志分析、数据挖掘的重要性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
import datetime
import re
from queue import Queue
import threading
from pathlib import Path
from user_agents import parse
from collections import defaultdict
 
 
# 正则,文件读取,时间窗口,队列,多线程,高阶函数,分发器,嵌套函数
 
logline = '''183.60.212.153 - - [19/Feb/2013:10:23:29 +0800] "GET /o2o/media.html?menu=3 HTTP/1.1" 200 16691 "-" "Mozilla/5.0 (compatible; EasouSpider; +http://www.easou.com/search/spider.html)"'''
 
pattern = '''(?P<remote_addr>[\d\.]{7,}) - - (?:\[(?P<datetime>[^\[\]]+)\]) "(?P<request>[^"]+)" (?P<status>\d+) (?P<size>\d+) "[^"]+" "(?P<useragent>[^"]+)"'''
 
# 数据源处理
ops = {
    'datetime'lambda timestr: datetime.datetime.strptime(timestr, "%d/%b/%Y:%H:%M:%S %z"),
    'request'lambda request: dict(zip(('method''url''protocol'), request.split())),
    'status'int,
    'size'int,
    'useragent'lambda useragent: parse(useragent)
}
 
regex = re.compile(pattern)
 
def extract(line):
    matcher = regex.match(line)
    if matcher:
        return {k: ops.get(k, lambda x: x)(v) for k, v in matcher.groupdict().items()}
 
 
def openfile(path:str):
    with open(path) as f:
        for line in f:
            fields = extract(line)
            if fields:
                yield fields  # return generator objects,next(load(path))
            else:
                # TODO 不合格数据有哪些
                continue  # TODO 解析失败就抛弃,或者打印日志
 
 
def load(*paths):
    '''装载日志文件或路径'''
    for item in paths:
        = Path(item)
        if not p.exists():
            continue
 
        if p.is_dir():
            for file in p.iterdir():
                if file.is_file():
                    yield from openfile(str(file))
        elif p.is_file():
            yield from openfile(str(p))
 
 
def window(src:Queue, handler, width: int, interval: int):
    '''
    窗口函数
    :param src: 数据源,生成器,用来拿数据
    :param handler: 数据处理函数
    :param width: 时间窗口宽度,秒
    :param interval: 处理时间间隔,秒/ 时间偏移量,秒
    :return:
    '''
 
    start = datetime.datetime.strptime('1970/01/01 01:01:01 +0800''%Y/%m/%d %H:%M:%S %z')
    current = datetime.datetime.strptime('1970/01/01 01:01:02 +0800''%Y/%m/%d %H:%M:%S %z')
    delta = datetime.timedelta(seconds=width-interval)
 
    buffer = []  #窗口里的待计算数据
 
    while True:  #while True方式迭代queue
        # 从数据源获取数据
        data = src.get()   # block阻塞的
 
        if data:
            buffer.append(data)
            current = data['datetime']
 
        if (current - start).total_seconds() >= interval:
            ret = handler(buffer)      # 如何处理
            print("{}".format(ret))
 
            start = current
 
            buffer = [i for in buffer if i['datetime'] > current - delta]
 
 
def donothing_handler(iterable:list):
    # print(iterable)
    return iterable
 
 
# 状态码时间段百分比分析
def status_handler(iterable:list):
    = {}
    for item in iterable:
        key = item['status']
        if key not in d:
            d[key] = 0
        d[key] += 1
 
    total= sum(d.values())
    return {'{}: {:.2f}%'.format(k,v/total*100for k,v in d.items()}
 
 
# 浏览器分析函数
ua_dict = defaultdict(lambda 0)  # 作用域改为全局之后,字典递增保存所有ua及其版本
def browser_handler(iterable):
    for item in iterable:
        ua = item['useragent']
        key = (ua.browser.family, ua.browser.version_string)
        ua_dict[key] += 1
    return ua_dict
 
 
# 分发器,嵌套函数
def dispatcher(src):
    queues = []  # 队列列表
    threads = []  # 线程管理
 
    def reg(handler, width, interval):
        = Queue()    # 分配队列
        queues.append(q)  # 方便调用
 
        = threading.Thread(target=window,args=(q, handler, width, interval))
        threads.append(t)
 
 
 
    def run():
        for in threads:
            t.start()
 
        for in src:
            for in queues:
                q.put(x)
 
    return reg,run
 
     
reg,run = dispatcher(load('test.log'))
 
# reg注册 窗口
# reg(donothing_handler, 10, 5)    #注册测试
# reg(status_handler, 10, 5)       # 注册状态码处理函数
reg(browser_handler, 6060)       # 注册useragent处理函数,注意时间窗口宽度
 
run()

(转)Python 日志处理(三) 日志状态码分析、浏览器分析的更多相关文章

  1. 利用python完成多个url状态码的检测

    import re import requests import json from threading import Thread,Lock from concurrent.futures impo ...

  2. HTTP学习记录:三、状态码

    学习资源主要为:@小坦克HTTP相关博客 常见的HTTP状态码: 200--请求成功: 302--重定向: 304--Not Modified:表示上次的文档已经被缓存了,还可以继续使用: 400-- ...

  3. HTTP协议图--HTTP 响应状态码(重点分析)

    1. 状态码概述 HTTP 状态码负责表示客户端 HTTP 请求的返回结果.标记服务器端的处理是否正常.通知出现的错误等工作. HTTP 状态码如 200 OK ,以 3 位数字和原因短语组成.数字中 ...

  4. python 使用异常代替返回状态码

  5. Python 日志处理(三) 日志状态码分析、浏览器分析

    在企业中,从日志中提取数据进行分析,可以帮助企业更加了解用户行为,用户最感兴趣的产品或者内容,分析得到数据后,可以决定企业在今后的走向. 从这些日志数据中,比较重要的有: 1. 用户访问最多的url, ...

  6. nginx 499状态码

    Web服务器在用着nginx,在日志中偶尔会看到有499这个错误. rfc2616中,400-500间的错误码仅定义到了417,所以499应该是nginx自己定义的.后来想到读读nginx代码,疑问立 ...

  7. Nginx_HTTP 499 状态码 nginx下 499错误

    日志记录中HTTP状态码出现499错误有多种情况,我遇到的一种情况是nginx反代到一个永远打不开的后端,就这样了,日志状态记录是499.发送字节数是0. 老是有用户反映网站系统时好时坏,因为线上的产 ...

  8. HTTP 499 状态码 nginx下 499错误[转]

    日志记录中HTTP状态码出现499错误有多种情况,我遇到的一种情况是nginx反代到一个永远打不开的后端,就这样了,日志状态记录是499.发送字节数是0. 老是有用户反映网站系统时好时坏,因为线上的产 ...

  9. HTTP 499 状态码 nginx下 499错误

    日志记录中HTTP状态码出现499错误有多种情况,我遇到的一种情况是nginx反代到一个永远打不开的后端,就这样了,日志状态记录是499.发送字节数是0. 老是有用户反映网站系统时好时坏,因为线上的产 ...

随机推荐

  1. jmeter读取csv文件

    操作步骤: 1.读取csv文件 2.编辑httpSampler

  2. js中如何将数据获得2位小数以及对数据进行千分位划分

    js中toFixed(n) 方法可把 数字四舍五入为指定小数位数n的数字,注意:这个方法只能对数据类型为Number的数据起作用,包括float,int等.例如:   123.12345.toFixe ...

  3. __cxa_call_unexpected原因

    coredump的调用栈: #0  0xf76f5440 in __kernel_vsyscall () #1  0xf73c4657 in raise () from /lib/libc.so.6 ...

  4. 顺序表[A+B->A]

    题目:表A 1  3  5,表B 2 4 6,都呈非递减排序,现将两个表合并成一个表,也呈非递减排序,存放在A中(或者B中),言外之意是不能开辟新表!拿出B中数据,沿着A的后面一直往前比较,如果小于就 ...

  5. 可以替代alert 的漂亮的Js弹框

    1 基本弹框 2确认框 3又一种确认框 4带返回的弹框 5带返回的探矿 6 6 一切尽在 http://t4t5.github.io/sweetalert/

  6. web-day11

    第11章WEB11-Cookie&Session篇 今日任务 显示用户的上次访问时间 登录系统以后显示商品浏览记录 购买商品将商品添加到购物车 系统登录的验证码的校验 教学导航 教学目标 了解 ...

  7. sdut 3916

    这道题就是二分枚举加贪心,小蓝书上一开始就讲的,但是我给忘了,很难受 #include <iostream> #include <cstdio> #include <cs ...

  8. unigui如何连接数据库

    unigui如何连接数据库 UNIGUI既可以二层直连数据库,也可以通过中间件连接数据库. 这里只介绍UNIGUI二层直连数据库. 数据库连接控件.数据集控件都要拖放在MainModule窗体上.UN ...

  9. 点聚weboffice插件自定义菜单

    https://blog.csdn.net/u014547764/article/details/53818637 1.在jsp中引用excel插件:首先项目中要有:WebOffice.zip.web ...

  10. 在.net中使用ETW事件的方法

    直到.net4.5,才有了比较便利的操作ETW的方法. 本文介绍的方法主要来源于Microsoft.Diagnostics.Tracing.TraceEvent官方资料库. 准备 (1)需要用到类:M ...