脚本统计ip的海外用户分布情况或者国内省份的分布情况

背景:日志文件会产生ip字段,现需要统计ip的分布情况

前提:必须有这么一个服务,输入指定的ip能返回相应的地理位置的信息。可以直接调用。

思想:首先提取出ip字段,一般用sed命令或者和cut结合。

例如,日志格式如下:

[INFO][2017-11-18 00:00:00] reqhandler.py 134, allocate, hid:XXXX msg:{'province': 'sn', 'ccid': -1, 'ip': 'xxx.xxx.xxx.xxx', 'isp': 'unicom', 'mid': 0, 'spaceid': '5A10BA4FCBB011E7A162000E1EFF0BA0', 'locator': 8, 'game': 10038, 'eid': 148079890, '_cmd_': 327681} 
可以用以下命令来提取ip字段。

grep "allocate," /home/XX/logs/*/XX.2017-11-17 | sed "s/^.* 'ip': '//g" | sed "s/', 'isp'.*//g" >> /home/XX/ip_1117.log

然后再用脚本去统计分布情况。(ip.mmdb 为一个ip映射的文件,此脚本用于统计国内省份分布情况)


# coding: utf8
import maxminddb
import csv


def get_country():
    reader = maxminddb.Reader('/home/XX/ip_log/ip.mmdb')

    en2zw = {}
    en2count = {}

    ips = get_record_from_file('/home/XX/ip_log/test.log')
    total_len = len(ips) / 1000
    count = 0
    for ip in ips:
        count += 1
        try:
            result = reader.get(ip)
            print result
        except Exception as ex:
            print ip, ex
            continue
        if not result:
            print ip, result
            continue
        zw = result['subdivisions']['names'].get('zh_CN', '')
        en = result['subdivisions']['names'].get('en', '')
        ct = result['country']['names'].get('en', '')
        print zw, en, ct
        if ct != 'China':
            continue

        if en not in en2zw:
            en2zw[en] = zw

        if en not in en2count:
            en2count[en] = 1
        else:
            en2count[en] += 1
    print '统计结果'
    print en2count
    en2count.pop('China', None)
    total = sum(en2count.values()) * 1.0
    print 'total:', total
    for en, count in en2count.iteritems():
        print 'en:%s, zh_CN: %s, count:%s percent:%s' % (en, en2zw.get(en), count, count / total)
def get_record_from_file(filename):
    u"""
    从文件中读取内容并放回,不适合操作大文件
    Args:
        filename {str} 文档的路径
    """
    ret = []
    with open(filename) as f:
        for record in f:
            record = record.strip()
            if not record:
                continue
            ret.append(record)
        return ret


if __name__ == '__main__':
    get_country()



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值