zoukankan      html  css  js  c++  java
  • 10min系列之二日志可视化进阶

    10min系列之二日志可视化进阶(作者原创,同步发布在github)

    本文需要有一定的python和前端基础,如果没基础的,请关注我后续的基础教程系列博客
    本文所有的demo,都是浏览器下展示的

    原创文章,本文同步发布在github,跪求github右上角star

    基于python,前端基于echarts,力求用简单的代码说明原理

    提纲

    • access日志按照什么维度展示数据
    • 和web结合,更好的体验,只需记住URL
    • 分页排序和搜索,表格展示体验的提升
    • 一图胜万言,汇总信息更友好的展示
    • 逼格满满,让IP信息在地图上展示
    • 后续展望--机房网络流量可视化,机器、机柜、机房3D展示
    • 希望能给大家带来一些处理log的思路

    背景

    老板要看日志数据汇总

    • 本文重点:如何做可视化
    • 目标:如何用友好的方式去展现沉闷繁冗的数据
    • 下个月就发年终奖!!!
    • 为了说明可视化的方式,用一个简单的log举例子

    原材料


    • 一个标准的access_log日志 大概2W行
    • 老板想要这个日志的分析结果,每个url,ip,status分别访问多少次,把前几名统计出来看看
    • 分析出统计数据 展现结果

    很普通的日志,大概长这样

    为了方便展示,切割了一下,大概2W行

    61.159.140.123 - - [23/Aug/2014:00:01:42 +0800] "GET /favicon.ico HTTP/1.1" 404  "-" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.66 Safari/537.36 LBBROWSER" "-"
    61.159.140.123 - - [23/Aug/2014:00:01:42 +0800] "GET /favicon.ico HTTP/1.1" 404  "-" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.66 Safari/537.36 LBBROWSER" "-"
    61.159.140.123 - - [23/Aug/2014:00:01:42 +0800] "GET /favicon.ico HTTP/1.1" 404  "-" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.66 Safari/537.36 LBBROWSER" "-"
    61.159.140.123 - - [23/Aug/2014:00:01:42 +0800] "GET /favicon.ico HTTP/1.1" 404  "-" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.66 Safari/537.36 LBBROWSER" "-"
    66.249.64.5 - - [23/Aug/2014:00:02:16 +0800] "GET /data/uploads/2013/0519/09/small_51982ba18e012.jpg HTTP/1.1" 200  "-" "Googlebot-Image/1.0" "-"
    66.249.64.10 - - [23/Aug/2014:00:02:54 +0800] "GET /data/uploads/2013/0319/08/middle_5147b116e93b4.jpg HTTP/1.1" 200  "-" "Googlebot-Image/1.0" "-"
    

    目标

    • 初级展现
    • 友好交互
    • 饼图汇总
    • 更进一步
    • 后续展望

    级别1


    • 数据处理,命令行展现
    • 打开文件,处理完数据后排序
    • 打印前10

    talk is cheap, show me the money code!

    # coding=utf-8
    f = open('www_access_20140823.log')
    res = {}
    for l in f:
        arr = l.split(' ')
        # 获取ip url 和status
        ip = arr[0]
        url = arr[6]
        status = arr[8]
        # ip url 和status当key,每次统计+1
        res[(ip,url,status)] = res.get((ip,url,status),0)+1
    # 生成一个临时的list
    res_list = [(k[0],k[1],k[2],v) for k,v in res.items()]
    # 按照统计数量排序,打印前10
    for k in sorted(res_list,key=lambda x:x[3],reverse=True)[:10]:
        print k
    

    处理结果

    ('222.86.153.12', '/images/cursor_minify.cur', '404', 60)
    ('222.86.153.12', '/images/cursor_zoom.cur', '404', 32)
    ('58.253.6.133', '/images/cursor_minify.cur', '404', 32)
    ('111.85.34.165', '/%3Ca%20href=', '404', 28)
    ('58.253.6.133', '/images/cursor_zoom.cur', '404', 27)
    ('218.29.111.117', '/images/cursor_zoom.cur', '404', 27)
    ('218.29.111.117', '/images/cursor_minify.cur', '404', 26)
    ('117.63.146.40', '/public/js/common.js?20110824', '200', 19)
    ('117.63.146.40', '/favicon.ico', '404', 18)
    ('117.63.146.40', '/public/js/weibo.js?20110824', '200', 16)
    

    任务完成

    • 下一步粘到邮件里,或者生成一个csv文件发出去
    • 然而这是一个看脸的社会,运维也逃脱不了这个魔咒

    级别2

    浏览器端展现

    生成list之后,拼接sql,存入数据库

    talk is cheap, show me the money code!

    import MySQLdb as mysql
    con = mysql.connect(user='root',
                        passwd='',
                        db='log',
                        host='localhost')
    con.autocommit(True)
    cur = con.cursor()
    # 处理文件省略
    for s in res_list:
        sql = 'insert log values ("%s","%s",%s,%s)' % s
        try:
            # 入库
            cur.execute(sql)
        except Exception, e:
            pass
    

    前端展现

    读库 展现页面

    talk is cheap, show me the money code!

    from flask import Flask,request,render_template
    app = Flask(__name__)
    import MySQLdb as mysql
    con = mysql.connect(user='xx',
                        passwd='xx',
                        db='xx')
    cur = con.cursor()
    @app.route('/')
    def index():
        table = '<table border="1">'
        cur.execute('select * from log order by value desc limit 20; ')
        for c in cur.fetchall():
            table += '<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>'%c
        table +='</table>'
        return table
    
    if __name__ == '__main__':
        app.run(host='0.0.0.0',port=9092)
    

    给老板一个url即可,老板想看随时能看

    表格

    但是老板表示有点丑

    老板

    完整的思路

    前端展现上做一些优化

    • 分页
    • 表格排序
    • 搜索
    • 控制每页显示数量
    • 数据多了之后,前端交互和后端数据的接口配合

    不动戳大

    我们的console页面,提供几个汇总信息,那就更好啦

    比如根据http的status来个汇总

    老板

    难不倒我

    一句sql搞定

    select status,sum(value) from log group by status
    +--------+------------+
    | status | sum(value) |
    +--------+------------+
    |    200 |      15529 |
    |    206 |          6 |
    |    301 |          2 |
    |    304 |       3549 |
    |    403 |          1 |
    |    404 |        847 |
    +--------+------------+
    6 rows in set (0.02 sec)
    

    汇总信息可视化

    根据https状态汇总

    其他功能

    • 图例开关
    • 图表转换
    • 数据视图
    • 直接导出图片

    可视化并不仅限于此

    上面只是举得小栗子

    如果你对时间更感兴趣,我们的log里也是有时间信息的,可以像下面这样

    统计量,时间轴拖动,保存图片,etc

    更进一步

    如何让日志数据更加一目了然,让老板觉得你很有逼格呢

    IP都是有地址位置的,定位每个ip的位置,画个地图出来汇总

    经纬度坐标系统

    • 地球坐标(WGS84)
      • 国际标准,从 GPS 设备中取出的数据的坐标系
      • 国际地图提供商使用的坐标系
    • 火星坐标(GCJ-02)
      • 中国标准,从国行移动设备中定位获取的坐标数据使用这个坐标系
    • 百度坐标(BD-09)
      • 百度标准,百度 SDK,百度地图,Geocoding 使用

    应用场景

    • WGS84坐标系:
      • 国际标准,谷歌国外地图、osm地图等国外的地图一般都是这个
    • 火星坐标系:
      • iOS 地图
      • Gogole地图
      • 搜搜、阿里云、高德地图
    • 百度坐标系:
      • 当然只有百度地图

    地图是需要经纬度的,用第三方的ip库转换一下

    http://developer.baidu.com/map/index.php?title=webapi/ip-api

    talk is cheap, show me the money code!

    import urllib2
    import json
    key = 'q5mTrTGzCSVq5QmGpI9y18Bo'
    ipurl = 'http://api.map.baidu.com/location/ip?ak='+key+'&coor=bd09ll&ip='
    sqlarr = []
    def getGeo(ip):
        try:
            u = urllib2.urlopen(ipurl+ip)
            page = json.load(u)
            if 'content' in page:
                point = page['content'].get('point')
                print 'ip %s has geoX %s and geoY %s' % (ip,point['x'],point['y']) 
        except:
            print 'error'
    getGeo('202.198.16.3')
    # ip 202.198.16.3 has geoX 125.31364243 and geoY 43.89833761
    

    就想玩网游时候,坐标可以定位一个人,经纬度可以再地图上定位一个点,画图展现

    刚才那个图仅关注区域,进阶一下,还要关注访问量

    可以根据value筛选

    进阶:多台机器的日志

    • 获取每个机器的hostname和ip,和日志数据一起存在数据库里
    • 一个表存日志,带上一个机器的id
    • 机器的id=>ip和经纬度
    • 最终统计访问量

    后续扩展

    • 日志数据
    • 前端展现场景

    怎么实践

    • 这次分享的主题关注与可视化
    • 我们用了一个很小的静态日志,目的是说明可视化的思路
    • 实际工作中日志数据应该怎么处理

    elk

    Logstash+ElasticSearch+Kibana4

    • logstash
      • 日志进行收集、分析,并将其存储供使用
    • ElasticSearch
      • 开源分布式搜索引擎,
    • Kibana4
      • 日志分析友好的 Web 界面
    • 其他
      • Kafka scribe等

    常见日志处理架构

    • ELK
    • logstash+Hadoop
    • scribe+hadoop
    • 线上数据->Flume->Kafka->Hdfs->Map/Reduce
    • 线上数据->flume->kafka->storm
    • 在上面的基础上定制化二次开发,比如MR平台上写代码,我们的代码就可以直接拿来用
    • 日志的数据处理架构详情,请见下回分解

    前端展现场景

    • 展现逼格更高一些,数据一样,效果更好
    • 运维人员权限树
    • 流量图
    • 年终数据统计
    • 区域点击统计图
    • 3D机房

    大家具体需要哪个,可以继续扩展,给大家展现几个假数据的demo

    高逼格饼图展示状态汇总(假数据,可以替换为http_status)

    人员权限树(假数据,可以作为运维人员权限展示)

    流量图(假数据,可以作为机房之间,或者网卡的流量)

    日志统计汇总(假数据,可以用来展示年日志数据汇总)

    区域数据汇总饼图展示(假数据,可选择省份,生成饼图)

    3D展示机房(网上盗图,后续会做一个类似的开源)

    json生成,实时查看机器状态,点击时间

    3D展示不止于此 有图有XX

    谢谢!

    原创文章,本文同步发布在github 继续求star

  • 相关阅读:
    模拟赛QAQ
    复习计划
    luogu P1080 国王游戏
    [NOIP2012T3]开车旅行
    luogu P1967 货车运输
    同余方程组的扩展欧几里得解法
    luogu P1476 休息中的小呆
    GRYZY #13. 拼不出的数
    GRYZY- #10. 财富
    GRYZY #8. 公交车
  • 原文地址:https://www.cnblogs.com/shengxinjing/p/5031699.html
Copyright © 2011-2022 走看看