- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
网络服务器日志分析器(例如 Urchin)通常会显示多个“ session ”。 session 定义为个人在有限的连续时间段内进行的一系列页面访问/点击。尝试使用 IP 地址以及用户代理和操作系统等补充信息以及 session 超时阈值(例如 15 或 30 分钟)来识别这些网段。
对于某些网站和应用程序,可以使用 cookie 登录和/或跟踪用户,这意味着服务器可以准确地知道 session 何时开始。我不是在谈论那个,而是在 Web 服务器不跟踪它们时启发式地推断 session (“session reconstruction”)。
我可以写一些代码,例如在 Python 中尝试根据上述标准重建 session ,但我不想重新发明轮子。我正在查看大小约为 400K 行的日志文件,因此我必须小心使用可扩展算法。
我的目标是从日志文件中提取唯一 IP 地址列表,并针对每个 IP 地址从该日志中推断出 session 数。不需要绝对的精确度和准确度...相当不错的估计就可以了。
基于 this description :
a new request is put in an existing session if two conditions are valid:
- the IP address and the user-agent are the same of the requests already
inserted in the session,- the request is done less than fifteen minutes after the last request inserted.
从理论上讲,编写一个 Python 程序来构建字典(以 IP 为键)(以用户代理为键)的字典(以用户代理为键),其值为一对:( session 数,最新 session 的最新请求)在理论上很简单.
但我宁愿尝试使用现有的实现(如果可用的话),否则我可能会冒着花费大量时间调整性能的风险。
仅供引用,以免有人要求样本输入,这是我们日志文件的一行(已清理):
#Fields: date time s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent) cs(Referer) sc-status sc-substatus sc-win32-status
2010-09-21 23:59:59 215.51.1.119 GET /graphics/foo.gif - 80 - 128.123.114.141 Mozilla/5.0+(Windows;+U;+Windows+NT+5.1;+en-US;+rv:1.9.2)+Gecko/20100115+Firefox/3.6+(.NET+CLR+3.5.30729) http://www.mysite.org/blarg.htm 200 0 0
最佳答案
好的,在没有任何其他答案的情况下,这是我的 Python 实现。我不是 Python 专家。欢迎提出改进建议。
#!/usr/bin/env python
"""Reconstruct sessions: Take a space-delimited web server access log
including IP addresses, timestamps, and User Agent,
and output a list of the IPs, and the number of inferred sessions for each."""
## Input looks like:
# Fields: date time s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent) cs(Referer) sc-status sc-substatus sc-win32-status
# 2010-09-21 23:59:59 172.21.1.119 GET /graphics/foo.gif - 80 - 128.123.114.141 Mozilla/5.0+(Windows;+U;+Windows+NT+5.1;+en-US;+rv:1.9.2)+Gecko/20100115+Firefox/3.6+(.NET+CLR+3.5.30729) http://www.site.org//baz.htm 200 0 0
import datetime
import operator
infileName = "ex100922.log"
outfileName = "visitor-ips.csv"
ipDict = {}
def inputRecords():
infile = open(infileName, "r")
recordsRead = 0
progressThreshold = 100
sessionTimeout = datetime.timedelta(minutes=30)
for line in infile:
if (line[0] == '#'):
continue
else:
recordsRead += 1
fields = line.split()
# print "line of %d records: %s\n" % (len(fields), line)
if (recordsRead >= progressThreshold):
print "Read %d records" % recordsRead
progressThreshold *= 2
# http://www.dblab.ntua.gr/persdl2007/papers/72.pdf
# "a new request is put in an existing session if two conditions are valid:
# * the IP address and the user-agent are the same of the requests already
# inserted in the session,
# * the request is done less than fifteen minutes after the last request inserted."
theDate, theTime = fields[0], fields[1]
newRequestTime = datetime.datetime.strptime(theDate + " " + theTime, "%Y-%m-%d %H:%M:%S")
ipAddr, userAgent = fields[8], fields[9]
if ipAddr not in ipDict:
ipDict[ipAddr] = {userAgent: [1, newRequestTime]}
else:
if userAgent not in ipDict[ipAddr]:
ipDict[ipAddr][userAgent] = [1, newRequestTime]
else:
ipdipaua = ipDict[ipAddr][userAgent]
if newRequestTime - ipdipaua[1] >= sessionTimeout:
ipdipaua[0] += 1
ipdipaua[1] = newRequestTime
infile.close()
return recordsRead
def outputSessions():
outfile = open(outfileName, "w")
outfile.write("#Fields: IPAddr Sessions\n")
recordsWritten = len(ipDict)
# ipDict[ip] is { userAgent1: [numSessions, lastTimeStamp], ... }
for ip, val in ipDict.iteritems():
# TODO: sum over on all keys' values [(v, k) for (k, v) in d.iteritems()].
totalSessions = reduce(operator.add, [v2[0] for v2 in val.itervalues()])
outfile.write("%s\t%d\n" % (ip, totalSessions))
outfile.close()
return recordsWritten
recordsRead = inputRecords()
recordsWritten = outputSessions()
print "Finished session reconstruction: read %d records, wrote %d\n" % (recordsRead, recordsWritten)
更新:这花了 39 秒来输入和处理 342K 条记录并写入 21K 条记录。对于我的目的来说,这个速度已经足够了。显然 3/4 的时间花在了 strptime()
上!
关于python - 从 web 服务器日志中免费实现用户 session 计数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3773840/
前言 俗话说得好“工欲善其事,必先利其器”,合理的选择和使用可视化的管理工具可以降低技术入门和使用的门槛。今天大姚给大家分享一款.NET Avalonia开源、免费、跨平台、快速的Git可视化管理工
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题? Update the question所以它是on-topic对于堆栈溢出。 9年前关闭。 Improve this que
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
正在学习有关 C 语言链接列表的教程。我已编译此代码并通过 valgrind 运行它。它显示了 4 次分配和 0 次释放,这是我理解的。我需要知道如何正确调用 free() 来释放分配。 代码示例:l
正如标题所说,我需要一个搜索引擎...用于mysql 搜索。我的网站是基于 PHP 的。 我打算使用 sphinx,但我的托管公司不支持全文索引! 所以一个没有全文的搜索引擎! 它应该是相当强大的,并
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 6年前关闭。 Improve thi
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 2 年前。
我正在寻找稳定和成熟的免费/开源库来比较两个图像。 我找到了这个,但我想知道你是否使用更好的! Similar images finder - .NET Image processing in C#
我有一个通用链表实现,其中包含一个指向数据的 void* 的节点结构和一个包含对头的引用的列表结构。现在这是我的问题,链表中的一个节点可能通过其 void* 持有对另一个链表的引用。当我释放包含较小列
前言 今天大姚给大家分享一款开源(MIT License)、免费、现代化风格的WPF UI控件库:ModernWpf。 项目介绍 ModernWpf是一个开源项目,它为 WPF 提供了一组现代化
LiveCharts2 LiveCharts2是一个.NET开源(MIT License)、简单、灵活、交互式且功能强大的.NET图表、地图和仪表,现在几乎可以在任何地方运行如:Maui、Uno P
前言 今天大姚给大家分享一款.NET开源(MIT License)、免费、实用的多功能原神工具箱,旨在改善桌面端玩家的游戏体验:胡桃工具箱。 工具箱介绍 胡桃工具箱是一款.NET开源(MIT
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 想改进这个问题?将问题更新为 on-topic对于堆栈溢出。 3年前关闭。 Improve this qu
当我这样做时,我的 meteor 应用程序运行的免费服务器的规范是什么。 meteor deploy myapp.meteor.com 规范方面 Storage size Max bandwidth
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 7年前关闭。 Improve thi
如果可能,我可以使用任何网络服务免费存储少量数据(考虑 XML 或 JSON)? 我想我想创建一个小型待办事项应用程序,只是探索/学习(最好是免费的),它还可以将数据备份到云端,以便他们可以在智能手机
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 想改进这个问题?将问题更新为 on-topic对于堆栈溢出。 2年前关闭。 Improve this qu
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 6年前关闭。 Improve thi
是否有任何免费/开源替代 Codesmith 可以在功能上进行比较并生成 .NET 代码? 最佳答案 几年前我做了同样的研究,发现 MyGeneration 成为 非常好。 关于.net - 免费 C
在尝试找到可以逐步执行/允许线程的haskell monad时,我发现了免费的monad data Free f a = Return a | Roll (f (Free f a)) 及其 monad
我是一名优秀的程序员,十分优秀!