您好,首先对不起,如果问题描述听起来很奇怪和不精确。用英语描述我的复杂问题对我来说并不容易,但我希望你能理解我的意思。
我制作了一个用于解析Webserver访问日志的CLI工具。我专注于性能和使用灵活性。
因此我使用MMap将LogFiles读入内存,然后将内存映射的char *传递给并行的OpenMP处理循环。
在omp parallel for循环中,我只使用boost :: regex_search解析每个LogString中的几个信息性子串,并将事件数据存储在线程本地自定义LogEvent类型的Object中。
从当前字符串创建此LogEvent-Object后,我将LogEvent附加到向量并继续解析下一个String,依此类推。
棘手的是我在程序启动时解析用户配置文件。用户可以通过指定与数据匹配的字段名称和RegEx来定义多个“数据字段”。
E.g:
Time = \d{2}\/\w{3}\/\d{4}
IP = \d{1,3}\.\d{1,3}.\d{1,3}.\d{1,3}
Object = \d{2,8}\_w\d{1,3}.mp4|\d{2,10}.flv
此外,用户可以指定生成输出报告数据的顺序
E.g:
field_0 = %IP%
field_1 = %Object%
field_2 = %Time%
输出字符串可能如下所示:
10.20.30.1;video_xyz.flv;Jul/23/2011:11:12;3
10.20.30.1;video_xyz.flv;Jul/23/2011:11:17;1
10.20.30.1;video_xyz.flv;Jul/23/2011:11:18;12
10.11.30.1;video_xyz.blabla.mp4;Jul/23/2011:11:12;3
我遇到的问题是,流式传输视频文件会导致日志中出现多个访问事件。我无法真正认识到有人只是重新加载/缓冲流,因为不同的客户端平台在生成服务器响应代码时会有不同的行为。
现在我多次计算事件,这往往是错误的。
我该如何处理这个问题?我知道这很普遍,但是如果你考虑我的程序以及我如何描述它,你很快就会发现我的程序设计很难解决这个问题。
我找到了一种或另一种解决方法,但它始终是一种非常糟糕的性能影响,而不是一种合法的解决方案。
不知何故,我必须避免在解析时将这些LogEvent附加到LogEvent-Objects的向量中,因为在此之前字符串仍然按照正确的时间顺序排列,所以我可以将当前字符串与之前的字符串进行比较,依此类推。
在那之后,omp关键阶段开始并且线程局部结果被组合,如果我想检查错误的多次命中计数,我将不得不搜索整个数据阵列nogo。
我希望我的问题足够明确。有任何想法吗? (如果示例代码有帮助,不知道,因为我认为这更像是设计问题)...
答案 0 :(得分:0)
好的,最后我找到了一个可以忍受一段时间的解决方法。
在解析字符串时,我总是从每个日志字符串中获取IP地址和目标项。
我有一个线程本地地图,将IP-Adress存储为密钥,将目标项目(例如视频流)存储为值。
每当我想要计算我之前检查的logevent时,如果当前处理的LogsStrings的IP地址已经是我的线程本地Map的键。
如果不是,那么计算事件是安全的。我将当前IP添加为密钥,将Object添加为值,这意味着我将更新此特定IP的最后访问对象。
如果它已经是我的地图的一个键,我检查这个键的值(目标项)是否与我当前的LogStrings目标相同。
如果是这样,那只是意味着该用户上次访问我服务器上的任何内容时都是访问同一视频流。
当对象发生变化时,我只会继续统计来自此IP地址的事件。
因为用户不太可能从一个流切换到另一个流然后返回(即使他计算它是正确的)所以看起来我们在这里得到了一个新事件,我们真的想要数
这有点像反向灰名单。任何ip只计算一次,然后阻止计数,直到由于新对象而生成新签名。
当然,如果您有任何更好的想法,这也会对性能产生影响,请随时回答:P