代码:

# pv_day.py
#!/usr/bin/env python
# coding=utf-8 from mrjob.job import MRJob
from nginx_accesslog_parser import NginxLineParser class PvDay(MRJob): nginx_line_parser = NginxLineParser() def mapper(self, _, line): self.nginx_line_parser.parse(line)
day, _ = str(self.nginx_line_parser.time_local).split()
yield day, 1 # 每一天的 def reducer(self, key, values):
yield key, sum(values) def main():
PvDay.run() if __name__ == '__main__':
main()

代码解释:

定义了一个集成MRJob类的job类,这个类包含定义好的steps。

一个‘step’包含一个mapper,combiner和一个reducer,这些是可选的,但是必须使用至少一个。

mapper()方法有两个参数key,value(这个例子中,key被忽略,每行日志作为一个value),并生成key-value对。

reduce()方法接受一个key和一个可迭代的values,并生成许多key-value对(这个例子中,计算每个key对应values值得和,也就是每天对应的PV)。

以不同方式执行job:

基本方式:

# python3 pv_day.py access_all.log-20161227
No configs found; falling back on auto-configuration
Creating temp directory /tmp/pv_day.root.20161228.022837.113256
Running step 1 of 1...
Streaming final output from /tmp/pv_day.root.20161228.022837.113256/output...
"2016-12-27" 47783
"2016-12-26" 299427
Removing temp directory /tmp/pv_day.root.20161228.022837.113256...

标准输入stdin方式,这种方式只接受第一个文件

# python3 pv_day.py < access_all.log-20161227
No configs found; falling back on auto-configuration
Creating temp directory /tmp/pv_day.root.20161228.024431.884434
Running step 1 of 1...
reading from STDIN
Streaming final output from /tmp/pv_day.root.20161228.024431.884434/output...
"2016-12-27" 47783
"2016-12-26" 299427
Removing temp directory /tmp/pv_day.root.20161228.024431.884434...

混合方式:

python3 pv_day.py input1.txt input2.txt - < input3.txt

分布式:

默认情况下,mrjob执行job使用单个Python进程,这里只是调试,并不是精确的分布式计算!

如果使用分布式计算,可以使用 -r/--runner选项。 使用 -r inline(默认), -r local, -r hadoop, -r emr

# python pv_day.py -r hadoop hdfs://my_home/input.txt

另一种方法:

# cat pv_day1.py
#!/usr/bin/env python
# coding=utf-8 from mrjob.job import MRJob
from mrjob.step import MRStep
from nginx_accesslog_parser import NginxLineParser class PvDay(MRJob): nginx_line_parser = NginxLineParser() def mapper(self, _, line): self.nginx_line_parser.parse(line)
day, _ = str(self.nginx_line_parser.time_local).split()
yield day, 1 # 每一天的
yield 'total', 1 # 总的 def reducer_sum(self, key, values):
yield None, (sum(values), key) def reducer_sort(self, _, values): for count, dt in sorted(values, reverse=True):
yield dt, count def steps(self): return (
MRStep(mapper=self.mapper,
reducer=self.reducer_sum),
MRStep(reducer=self.reducer_sort)
) def main():
PvDay.run() if __name__ == '__main__':
main()

执行结果:

# python3 pv_day1.py access_all.log-20161227
No configs found; falling back on auto-configuration
Creating temp directory /tmp/pv_day1.root.20161228.061455.974823
Running step 1 of 2...
Running step 2 of 2...
Streaming final output from /tmp/pv_day1.root.20161228.061455.974823/output...
"total" 347210
"2016-12-26" 299427
"2016-12-27" 47783
Removing temp directory /tmp/pv_day1.root.20161228.061455.974823...

二、基于hadoop的nginx访问日志分析---计算日pv的更多相关文章

  1. 三、基于hadoop的nginx访问日志分析--计算时刻pv

    代码: # cat pv_hour.py #!/usr/bin/env python # coding=utf-8 from mrjob.job import MRJob from nginx_acc ...

  2. 一、基于hadoop的nginx访问日志分析---解析日志篇

    前一阵子,搭建了ELK日志分析平台,用着挺爽的,再也不用给开发拉各种日志,节省了很多时间. 这篇博文是介绍用python代码实现日志分析的,用MRJob实现hadoop上的mapreduce,可以直接 ...

  3. 四、基于hadoop的nginx访问日志分析---top 10 request

    代码: # cat top_10_request.py #!/usr/bin/env python # coding=utf-8 from mrjob.job import MRJob from mr ...

  4. 五、基于hadoop的nginx访问日志分析--userAgent和spider

    useragent: 代码(不包含蜘蛛): # cat top_10_useragent.py #!/usr/bin/env python # coding=utf-8 from mrjob.job ...

  5. nginx访问日志分析,筛选时间大于1秒的请求

    处理nginx访问日志,筛选时间大于1秒的请求   #!/usr/bin/env python ''' 处理访问日志,筛选时间大于1秒的请求 ''' with open('test.log','a+' ...

  6. Nginx 访问日志分析

    0:Nginx日志格式配置 # vim nginx.conf ## # Logging Settings ## log_format access '$remote_addr - $remote_us ...

  7. Nginx访问日志分析

    nginx默认的日志格式 log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$sta ...

  8. 13 Nginx访问日志分析

    #!/bin/bash export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin # Nginx 日志格式: # ...

  9. 利用GoAccess分析Nginx访问日志

    原文链接:https://blog.csdn.net/yown/article/details/56027112 需求:及时得到线上用户访问日志分析统计结果,以便给开发.测试.运维.运营人员提供决策! ...

随机推荐

  1. ADT - Eclipse 常用快捷键

    ADT - Eclipse 常用快捷键 Alt + / : 自动补全 F3 : 打开类的源码 Ctrl + D : 删除选中行 Ctrl + 1 : 自动弹出修改建议 Ctrl + Shift + J ...

  2. IT菜鸟的生存指南(二)新手村任务

    此文献给那些刚误入IT行业的小菜鸟们,此文无法教你如何"当上CEO,迎娶白富美",那是电视剧情.现实IT行业里危机重重,竞争激励.这里教你的是如何生存.生存.生存- 恭(不)喜(幸 ...

  3. 安卓开发之ListAdapter(二)

    今天我们来学习一下ArrayAdapter: ArrayAdapter是安卓中最简单的适配器.使用ArrayAdapter(数组适配器),需要把数据源存 放至数组里面来显示. •构造函数: publi ...

  4. 改变Activity启动时的默认动画

    why 在开发中我们可能需要改变这一行为,一般基于2种理由: 产品的spec这么要求的: 想自己控制这个行为,因为在Android设备上可能每个的这一默认行为都不一样,厂商可以很容易修改它,从而导致a ...

  5. MySql索引总结

    索引概念 B+树索引分为聚集索引和非聚集索引(辅助索引),但是两者的数据结构都和B+树一样,区别是存放的内容. 可以说数据库必须有索引,没有索引则检索过程变成了顺序查找,O(n)的时间复杂度几乎是不能 ...

  6. centos7 apache httpd安装和配置django项目

    一.安装httpd服务 apache在centos7中是Apache HTTP server.如下对httpd的解释就是Apache HTTP Server.所以想安装apache其实是要安装http ...

  7. linux查看cpu 命令

    总核数 = 物理CPU个数 * 每颗物理CPU的核数 总逻辑CPU数 = 物理CPU个数 * 每颗物理CPU的核数 * 超线程数 查看物理CPU个数 cat /proc/cpuinfo| grep & ...

  8. [LeetCode] Longest Substring with At Most Two Distinct Characters 最多有两个不同字符的最长子串

    Given a string S, find the length of the longest substring T that contains at most two distinct char ...

  9. [Java]使用HttpClient实现一个简单爬虫,抓取煎蛋妹子图

    第一篇文章,就从一个简单爬虫开始吧. 这只虫子的功能很简单,抓取到”煎蛋网xxoo”网页(http://jandan.net/ooxx/page-1537),解析出其中的妹子图,保存至本地. 先放结果 ...

  10. IT培训行业揭秘(二)

    培训机构与高校之间是怎么"勾结"的? 每一个做院招的培训机构通常会有一个“院校关系”部门,这个部门就是专门为培训机构做疏通培训班与高校之间的关系的,通常这个部门都会拥有一张各大高校 ...