摘要:在這個筆記中,我們將展示一個使用分析訪問日志的簡單示例。加載和解析數(shù)據(jù)我們將需要模塊,用來解析日志。我們也需要知道設(shè)置在配置中的日志格式。實際上,在這個示例中不管我們使用哪個變量,這些數(shù)字將表明有多少次請求該網(wǎng)站的信息請求。
本文的作者是 Nikolay Koldunov,本文原文是
Apache log analysis with Pandas
注本文的圖有問題,沒法引用,還是去原文看下,這里作為一個引子。
%pylab inline
歡迎來到 pylab,一個基于 matplotlib 的 Python 環(huán)境【backend: module://IPython.kernel.zmq.pylab.backend_inline】。想要了解更多信息,請鍵入 "help(pylab)"。
在這個筆記中,我們將展示一個使用 pandas 分析 Apache 訪問日志的簡單示例。這是我第一次使用 pandas,并且我確定會有更好以及更有效率的方式來做這里展示的事情。所以評論,建議和修正我的蹩腳英語是非常歡迎的。你可以給我發(fā)送郵件或者是為這個筆記的 github 創(chuàng)建一個 PR。
加載和解析數(shù)據(jù)我們將需要 apachelog 模塊,用來解析日志。我們也需要知道設(shè)置在 Apache 配置中的日志格式。在我的案例中,我沒有訪問 Apache 配置,但是主機(jī)托管服務(wù)提供商在他的幫助頁提供了日志格式的描述。下面是它自己的格式以及每個元素的簡單描述:
format = r"%V %h %l %u %t "%r" %>s %b "%i" "%{User-Agent}i" %T"
這里(大部分拷貝自這個 SO 文章):
%V - 根據(jù) UseCanonicalName 設(shè)置的服務(wù)器名字 %h - 遠(yuǎn)程主機(jī)(客戶端 IP) %l - identity of the user determined by identd (not usually used since not reliable) %u - 由 HTTP authentication 決定的 user name %t - 服務(wù)器完成處理這個請求的時間 %r - 來自客戶端的請求行。 ("GET / HTTP/1.0") %>s - 服務(wù)器端返回給客戶端的狀態(tài)碼(200, 404 等等。) %b - 響應(yīng)給客戶端的響應(yīng)報文大小 (in bytes) "%i" - Referer is the page that linked to this URL. User-agent - the browser identification string %T - Apache 請求時間
In [3]:import apachelog, sys
設(shè)置格式:
In [4]:fformat = r"%V %h %l %u %t "%r" %>s %b "%i" "%{User-Agent}i" %T"
創(chuàng)建一個解析器:
In [5]:p = apachelog.parser(fformat)
簡單字符串:
koldunov.net 85.26.235.202 - - [16/Mar/2013:00:19:43 +0400] "GET /?p=364 HTTP/1.0" 200 65237 "http://koldunov.net/?p=364" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11" 0
In [6]:sample_string = "koldunov.net 85.26.235.202 - - [16/Mar/2013:00:19:43 +0400] "GET /?p=364 HTTP/1.0" 200 65237 "http://koldunov.net/?p=364" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11" 0"
In [7]:data = p.parse(sample_string)
In [8]:data
Out[8]: {"%>s": "200", "%T": "0", "%V": "koldunov.net", "%b": "65237", "%h": "85.26.235.202", "%i": "http://koldunov.net/?p=364", "%l": "-", "%r": "GET /?p=364 HTTP/1.0", "%t": "[16/Mar/2013:00:19:43 +0400]", "%u": "-", "%{User-Agent}i": "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11"}
這就是解釋器的工作。現(xiàn)在讓我們加載真實世界的數(shù)據(jù)(示例文件位于這里和這里):
In [9]:log = open("access_log_for_pandas").readlines()
解析每一行,并且創(chuàng)建一個字典列表:
In [10]: log_list = [] for line in log: try: data = p.parse(line) except: sys.stderr.write("Unable to parse %s" % line) data["%t"] = data["%t"][1:12]+" "+data["%t"][13:21]+" "+data["%t"][22:27] log_list.append(data)
我們不得不調(diào)整時間格式位,否則的話 pandas 將不能解析它。
創(chuàng)建和調(diào)整數(shù)據(jù)幀這將創(chuàng)建一個字典列表,可以轉(zhuǎn)化到一個數(shù)據(jù)幀:
import pandas as pd import numpy as np from pandas import Series, DataFrame, Panel
df = DataFrame(log_list)
展示數(shù)據(jù)幀的前兩行:
df[0:2]
- | %>s | %T | %V | %b | %h | %i | %l | %r | %t | %u | %{User-Agent}i |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 200 | 0 | www.oceanographers.ru | 26126 | 109.165.31.156 | - | - | GET /index.php?option=com_content&task=section... | 16/Mar/2013 08:00:25 +0400 | - | Mozilla/5.0 (Windows NT 6.1; rv:19.0) Gecko/20... |
1 | 200 | 0 | www.oceanographers.ru | 10532 | 109.165.31.156 | http://www.oceanographers.ru/index.php?option=... | - | GET /templates/ja_procyon/css/template_css.css... | 16/Mar/2013 08:00:25 +0400 | - | Mozilla/5.0 (Windows NT 6.1; rv:19.0) Gecko/20... |
我們不準(zhǔn)備使用所有的數(shù)據(jù),因此讓我們刪除一些列:
del df["%T"]; del df["%V"]; del df["%i"]; del df["%l"]; del df["%u"]; del df["%{User-Agent}i"]
并且把這些列重命名成人類可理解的格式:
df = df.rename(columns={"%>s": "Status", "%b":"b", "%h":"IP", "%r":"Request", "%t": "Time"})
結(jié)果數(shù)據(jù)幀的前 5 行:
df.head()
- | Status | b | IP | Request | Time |
---|---|---|---|---|---|
0 | 200 | 26126 | 109.165.31.156 | GET /index.php?option=com_content&task=section... | 16/Mar/2013 08:00:25 +0400 |
1 | 200 | 10532 | 109.165.31.156 | GET /templates/ja_procyon/css/template_css.css... | 16/Mar/2013 08:00:25 +0400 |
2 | 200 | 1853 | 109.165.31.156 | GET /templates/ja_procyon/switcher.js HTTP/1.0 | 16/Mar/2013 08:00:25 +0400 |
3 | 200 | 37153 | 109.165.31.156 | GET /includes/js/overlib_mini.js HTTP/1.0 | 16/Mar/2013 08:00:25 +0400 |
4 | 200 | 3978 | 109.165.31.156 | GET /modules/ja_transmenu/transmenuh.css HTTP/1.0 | 16/Mar/2013 08:00:25 +0400 |
轉(zhuǎn)換時間列成 datetime 格式并做一個索引出來(pop 將丟棄原始的 Time 列):
df.index = pd.to_datetime(df.pop("Time"))
Status 變量是一個 string 類型,因此我們需要把它轉(zhuǎn)換成 int:
df["Status"] = df["Status"].astype("int")
一些 b 列的行包含 "-" 字符,我們需要使用 astype 轉(zhuǎn)換它們:
df["b"][93]
Out[19]: "-"
我們可以為該列使用一個通用的函數(shù),它們將把所有的破折號轉(zhuǎn)換成 NaN,并且剩余的轉(zhuǎn)換成 floats,另外把 bytes 轉(zhuǎn)換成 megabytes:
def dash2nan(x): if x == "-": x = np.nan else: x = float(x)/1048576. return x
df["b"] = df["b"].apply(dash2nan)
我相信有一個更優(yōu)雅的方式來做到這一點。
流量分析首先,最簡單的散點:從該網(wǎng)站的出口流量:
df["b"].plot()
看起來在早上 9 點左右有人從網(wǎng)站下載了一些大的東西。
但是實際上你想知道的第一件事是你的網(wǎng)站有多少的訪問量,以及它們的時間分布。我們從 b 變量的 5 分鐘間隔重新取樣,并計算每個時間跨度的請求數(shù)。實際上,在這個示例中不管我們使用哪個變量,這些數(shù)字將表明有多少次請求該網(wǎng)站的信息請求。
df_s = df["b"].resample("5t", how="count") df_s.plot()
Out[23]:
![此處輸入圖片的描述][8]
我們不僅僅計算每個時間的請求數(shù),也計算每個時間段的總流量:
df_b = df["b"].resample("10t", how=["count","sum"]) df_b["count"].plot( color="r") legend() df_b["sum"].plot(secondary_y=True)
Out[24]:
![此處輸入圖片的描述][9]
正如你所看到的,服務(wù)器請求數(shù)和流量是不一致的,相關(guān)性其實并不是非常高:
df_b.corr()
|-| count| sum
|count| 1.000000| 0.512629
|sum| 0.512629| 1.000000
我們可以仔細(xì)看下早高峰:
df_b["2013-03-16 6:00":"2013-03-16 10:00"]["sum"].plot()
Out[26]:
![此處輸入圖片的描述][10]
看起來流量峰值是由一個請求引起的。讓我們找出這個請求。選擇所有響應(yīng)大于 20 Mb 的請求:
df[df["b"]>20]
- | Status | b | IP | Request |
---|---|---|---|---|
Time | ||||
2013-03-16 09:02:59 | 200 | 21.365701 | 77.50.248.20 | GET /books/Bondarenko.pdf HTTP/1.0 |
這是一本書的 pdf 文件,這就解釋了在 2013-03-16 09:02:59 的流量出口峰值。
接近 20 Mb 是一個大的請求(至少對于我們網(wǎng)站),但是服務(wù)器響應(yīng)的典型大小是?響應(yīng)大小(小于 20Mb)的立方圖看起來像這樣:
cc = df[df["b"]<20] cc.b.hist(bins=10)
Out[28]:
![此處輸入圖片的描述][11]
因此,大部分的文件是小于 0.5 Mb。實際上它們甚至更小:
cc = df[df["b"]<0.3] cc.b.hist(bins=100)
Out[29]:
![此處輸入圖片的描述][12]
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/37487.html
摘要:在這個筆記中,我們將展示一個使用分析訪問日志的簡單示例。加載和解析數(shù)據(jù)我們將需要模塊,用來解析日志。我們也需要知道設(shè)置在配置中的日志格式。實際上,在這個示例中不管我們使用哪個變量,這些數(shù)字將表明有多少次請求該網(wǎng)站的信息請求。 本文的作者是 Nikolay Koldunov,本文原文是Apache log analysis with Pandas 注本文的圖有問題,沒法引...
摘要:小安分析的數(shù)據(jù)主要是用戶使用代理訪問日志記錄信息,要分析的原始數(shù)據(jù)以的形式存儲。下面小安帶小伙伴們一起來管窺管窺這些數(shù)據(jù)。在此小安一定一定要告訴你,小安每次做數(shù)據(jù)分析時必定使用的方法方法。 隨著網(wǎng)絡(luò)安全信息數(shù)據(jù)大規(guī)模的增長,應(yīng)用數(shù)據(jù)分析技術(shù)進(jìn)行網(wǎng)絡(luò)安全分析成為業(yè)界研究熱點,小安在這次小講堂中帶大家用Python工具對風(fēng)險數(shù)據(jù)作簡單分析,主要是分析蜜罐日志數(shù)據(jù),來看看一般大家都使用代理i...
摘要:主頁暫時下線社區(qū)暫時下線知識庫自媒體平臺微博知乎簡書博客園我們不是的官方組織機(jī)構(gòu)團(tuán)體,只是技術(shù)棧以及的愛好者合作侵權(quán),請聯(lián)系請抄送一份到基礎(chǔ)編程思想和大數(shù)據(jù)中文文檔中文文檔中文文檔中文文檔中文文檔中文文檔中文文檔中文文檔中文文檔中文文檔區(qū)塊 【主頁】 apachecn.org 【Github】@ApacheCN 暫時下線: 社區(qū) 暫時下線: cwiki 知識庫 自媒體平臺 ...
摘要:主頁暫時下線社區(qū)暫時下線知識庫自媒體平臺微博知乎簡書博客園我們不是的官方組織機(jī)構(gòu)團(tuán)體,只是技術(shù)棧以及的愛好者合作侵權(quán),請聯(lián)系請抄送一份到基礎(chǔ)編程思想和大數(shù)據(jù)中文文檔中文文檔中文文檔中文文檔中文文檔中文文檔中文文檔中文文檔中文文檔中文文檔中文 【主頁】 apachecn.org 【Github】@ApacheCN 暫時下線: 社區(qū) 暫時下線: cwiki 知識庫 自媒體平臺 ...
摘要:首頁地址關(guān)于我們我們不是的官方組織機(jī)構(gòu)團(tuán)體,只是技術(shù)棧以及的愛好者基礎(chǔ)編程思想和大數(shù)據(jù)中文文檔中文文檔中文文檔中文文檔中文文檔中文文檔中文文檔中文文檔中文文檔中文文檔區(qū)塊鏈中文文檔數(shù)學(xué)筆記線性代數(shù)筆記數(shù)據(jù)科學(xué)中文文檔中文文檔中文文檔課本計算 首頁地址:http://www.apachecn.org關(guān)于我們:http://www.apachecn.org/about 我們不是 Apach...
閱讀 1264·2021-10-18 13:32
閱讀 2333·2021-09-24 09:47
閱讀 1323·2021-09-23 11:22
閱讀 2463·2019-08-30 14:06
閱讀 571·2019-08-30 12:48
閱讀 1997·2019-08-30 11:03
閱讀 535·2019-08-29 17:09
閱讀 2462·2019-08-29 14:10