R中的日志文件分析?

时间:2011-04-14 14:44:37

标签: r logfile-analysis

我知道还有其他工具,比如awstats或splunk,但我想知道是否有一些严重的(网络)服务器日志文件分析在R中进行。我可能不是第一个想到在R中做的,但仍然是R具有良好的可视化功能和漂亮的空间包。你知道吗?或者是否有一个R包/代码来处理可以构建的最常见的日志文件格式?或者这只是一个非常糟糕的主意?

5 个答案:

答案 0 :(得分:14)

与为我们的Network Ops人员构建分析工具箱的项目相关, 我在两个月前建造了其中一个。如果我开源,我的雇主没有问题,所以如果有人有兴趣我可以把它放在我的github回购上。我认为如果我构建一个R包,它对这个组最有用。我不能马上做到这一点 因为我需要研究使用非R代码构建包的文档(它可能就像在/ exec中使用合适的python运行时抛出python字节码文件一样简单,但我不知道)。

我真的很惊讶我需要进行这类项目。至少有几个优秀的开源和免费日志文件解析器/查看器(包括优秀的Webalyzer和AWStats),但是解析服务器错误日志(解析服务器访问日志是两者的主要用例)。

如果您不熟悉错误日志或它们与访问权限之间的区别 总而言之,Apache服务器(如iewsie,nginx和IIS)记录两个不同的日志,并默认将它们存储到磁盘,在同一目录中彼此相邻。在Mac OS X上, / var中的那个目录,就在root下面:

$> pwd
   /var/log/apache2

$> ls
   access_log   error_log

对于网络诊断,错误日志通常比访问日志更有用。 由于许多领域中数据的非结构化特性而且更重要的是,因为数据文件,它们也恰好更难以处理 在解析后是一个不规则的时间序列 - 你可能有多个条目键入一个时间戳,然后下一个条目是三秒钟后,依此类推。

我想要一个我可以在原始错误日志中丢弃的应用程序(任何大小,但通常一次只有几百MB)在另一端有一些有用的东西 - 在这种情况下,必须是一些预先R中包含的分析和数据立方体,用于命令行分析。鉴于此,我在python中编写了原始日志解析器,而处理器(例如,将解析器输出网格化以创建常规时间序列)以及所有分析和数据可视化,我用R编码。

我一直在构建分析工具很长一段时间,但仅限于过去 四年来我一直在使用R.所以我的第一印象 - 在解析原始日志文件并在R中加载数据框之后立即使用R是一种乐趣,以及它如何非常适合这种任务。一些受欢迎的企业:

  • <强> 序列化 即可。在R中保留工作数据是单个命令 (保存)。我知道这一点,但我不知道这个二进制文件有多高效 格式。实际数据:每解析50 MB原始日志文件,即 .RData表示大约500 KB - 100:1压缩。 (注意:我 通过使用data.table将其进一步降低到大约300:1 库并手动设置压缩级别参数以进行保存 功能);

  • <强> IO 即可。我的数据仓库在很​​大程度上依赖于轻量级数据结构 完全驻留在RAM中并写入磁盘的服务器 异步,称为redis。该方案本身只有两个左右 已经有几年了,但CRAN已经有了一个redis客户端(B.W. Lewis,版本1.6.1(截至本文);

  • 主要数据分析 。该项目的目的是建立一个 我们的网络Ops人员使用的库。我的目标是“一个命令= 一个数据视图“类型接口。所以,例如,我使用了优秀的 googleVis Package创建一个专业的外观 具有可排序列的可滚动/分页HTML表,其中i 加载了聚合数据的数据帧(> 5,000行)。只是那几个 交互式元素 - 例如,对列进行排序 - 交付有用 描述性分析。另一个例子,我写了很多 包装一些基本的数据杂耍和类似表格的函数;每 例如,我将这些函数绑定到可点击按钮 在选项卡式网页上。再一次,这在R中很高兴,部分原因 因为这个功能通常不需要包装器,单个 使用提供的参数的命令足以生成有用的 查看数据。

最后一颗子弹的几个例子:

# what are the most common issues that cause an error to be logged?

err_order = function(df){
    t0 = xtabs(~Issue_Descr, df)
    m = cbind( names(t0), t0)
    rownames(m) = NULL
    colnames(m) = c("Cause", "Count")
    x = m[,2]
    x = as.numeric(x)
    ndx = order(x, decreasing=T)
    m = m[ndx,]
    m1 = data.frame(Cause=m[,1], Count=as.numeric(m[,2]),
                    CountAsProp=100*as.numeric(m[,2])/dim(df)[1])
    subset(m1, CountAsProp >= 1.)
}

# calling this function, passing in a data frame, returns something like:


                        Cause       Count    CountAsProp
1  'connect to unix://var/ failed'    200        40.0
2  'object buffered to temp file'     185        37.0
3  'connection refused'                94        18.8


使用googleVis显示的主要数据多维数据集用于交互式分析

The Primary Data Cube Displayed for Interactive Analysis Using googleVis

使用googleVis显示的列联表(来自xtab函数调用) <
enter image description here

答案 1 :(得分:9)

这实际上是个好主意。 R还具有非常好的日期/时间功能,可以进行聚类分析或使用各种机器学习算法,有三种不同的正则表达式引擎来解析等。

这可能不是一个新奇的想法。几年前,我与使用R进行主动(而非被动)日志文件分析的人进行了简短的电子邮件联系:阅读日志,(在他们的例子中)构建时间序列模型,预测热点。这显然是一个好主意。它是能源部的实验室之一,但我不再拥有URL。即使在时间模式之外,也可以在这里做很多。

答案 2 :(得分:4)

我使用R来加载和解析IIS日志文件,这里有一些成功,这是我的代码。

Load IIS Log files
require(data.table)

setwd("Log File Directory")

# get a list of all the log files
log_files <- Sys.glob("*.log")

# This line
# 1) reads each log file
# 2) concatenates them
IIS <- do.call( "rbind", lapply( log_files,  read.csv, sep = " ", header = FALSE, comment.char = "#", na.strings = "-" ) )

# Add field names - Copy the "Fields" line from one of the log files :header line 
colnames(IIS) <- c("date", "time", "s_ip", "cs_method", "cs_uri_stem", "cs_uri_query", "s_port", "cs_username", "c_ip", "cs_User_Agent", "sc_status", "sc_substatus", "sc_win32_status", "sc_bytes", "cs_bytes", "time-taken")

#Change it to a data.table
IIS <- data.table( IIS )

#Query at will
IIS[, .N, by = list(sc_status,cs_username, cs_uri_stem,sc_win32_status) ]

答案 3 :(得分:1)

我最近使用R进行了日志文件分析。这不是真正的komplex事情,主要是描述性表格。 R的内置功能足以完成这项工作 问题是数据存储,因为我的日志文件大约是10 GB。 Revolutions R确实提供了处理这些大数据的新方法,但最后我决定使用MySQL数据库作为后端(实际上通过规范化将大小减小到2 GB)。 这也可以解决你在R中读取日志文件的问题。

答案 4 :(得分:1)

#!python

import argparse
import csv
import cStringIO as StringIO

class OurDialect:
    escapechar = ','
    delimiter = ' '
    quoting = csv.QUOTE_NONE


parser = argparse.ArgumentParser()
parser.add_argument('-f', '--source', type=str, dest='line', default=[['''54.67.81.141 - - [01/Apr/2015:13:39:22 +0000] "GET / HTTP/1.1" 502 173 "-" "curl/7.41.0" "-"'''], ['''54.67.81.141 - - [01/Apr/2015:13:39:22 +0000] "GET / HTTP/1.1" 502 173 "-" "curl/7.41.0" "-"''']])
arguments = parser.parse_args()

try:
    with open(arguments.line, 'wb') as fin:
        line = fin.readlines()
except: 
    pass
finally:
    line = arguments.line

header = ['IP', 'Ident', 'User', 'Timestamp', 'Offset', 'HTTP Verb', 'HTTP Endpoint', 'HTTP Version', 'HTTP Return code', 'Size in bytes', 'User-Agent']

lines = [[l[:-1].replace('[', '"').replace(']', '"').replace('"', '') for l in l1] for l1 in line]

out = StringIO.StringIO()

writer = csv.writer(out)
writer.writerow(header)

writer = csv.writer(out,dialect=OurDialect)
writer.writerows([[l1 for l1 in l] for l in lines])

print(out.getvalue())

演示输出:

IP,Ident,User,Timestamp,Offset,HTTP Verb,HTTP Endpoint,HTTP Version,HTTP Return code,Size in bytes,User-Agent
54.67.81.141, -, -, 01/Apr/2015:13:39:22, +0000, GET, /, HTTP/1.1, 502, 173, -, curl/7.41.0, -
54.67.81.141, -, -, 01/Apr/2015:13:39:22, +0000, GET, /, HTTP/1.1, 502, 173, -, curl/7.41.0, -

使用read.csv可以轻松地将此格式读入R.并且,它不需要任何第三方库。