您好,首先,如果问题描述听起来很奇怪和不精确,我很抱歉。对我来说,用英语描述我的复杂问题并不容易,但我希望你能理解我的意思。
我制作了一个CLI工具来解析for服务器访问日志。我关注的是性能和使用上的灵活性。
因此,我使用MMap将LogFiles读入内存,然后将内存映射的char*传递给一个并行的OpenMP处理循环。
在omp并行for循环中,我只使用boost::regex_search解析来自每个LogString的几个信息子字符串,并将事件数据存储在一个线程本地定制LogEvent类型的对象中。
在从当前字符串创建这个LogEvent-Object之后,我将LogEvent附加到一个向量,并继续解析下一个字符串,依此类推。
棘手的是,我在程序启动时解析用户配置文件。用户可以通过指定字段名称和与数据匹配的RegEx来定义多个“数据字段”。
例如:
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此外,用户可以指定生成输出报告数据的顺序
例如:
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 我的问题是,流式传输视频文件会在日志中引起几个访问事件。我真的无法识别有人只是重新加载/缓冲流,因为不同的客户端平台在生成服务器响应代码时有不同的行为。
现在,我会多次计算事件,但这往往是错误的。
我该如何处理这个问题?我知道这是相当普遍的,但是如果你思考我的程序以及我是如何描述它的,你很快就会发现这个问题很难用我的程序设计来解决。
我找到了一种或另一种解决方法,但它总是会对性能产生非常糟糕的影响,而且不是一个合法的解决方案。
我必须避免在解析时将这些LogEvents附加到LogEvent对象的向量中,因为在此之前,字符串仍然是按正确的时间顺序排列的,所以我可以将当前字符串与前一个字符串进行比较,以此类推。
在此之后,omp关键阶段开始,线程本地结果被合并,如果我想检查错误的多次命中计数,我将不得不搜索整个数据数组,这是nogo。
我希望我的问题已经足够清楚了。有什么想法吗?(不知道示例代码是否会有帮助,因为我认为这更多的是设计问题)……
发布于 2011-08-29 17:57:30
好吧,最后我找到了一个我可以接受一段时间的变通方法。
在解析字符串时,我现在总是从每个日志字符串中获取IP地址和目标项。
我有一个线程本地映射,它将IP地址存储为键,将目标项(例如视频流)存储为值。
每当我想要计算一个日志事件时,我会检查当前处理的LogsStrings的IP地址是否已经是我的线程本地Map的一个键。
如果不是,则可以安全地对事件进行计数。我添加当前IP作为键,添加Object作为值,这意味着我为这个特定的IP更新了最后访问的对象。
如果它已经是我的地图的一个键,我检查这个键的值(目标项)是否与我当前的LogStrings目标相同。
如果是这样的话,这可能意味着这个用户最后一次访问我的服务器上的任何东西是在访问相同的视频流时。
仅当对象发生更改时,我才会继续计数来自此IP地址的事件。
因为用户不太可能从一个流切换到另一个流,然后再切换回来(即使他会这样做,对它进行计数也是正确的),所以看起来我们在这里得到了一个新的事件,我们真的想对它进行计数。
这在某种程度上就像反向的灰色列表。任何ip只被计数一次,然后被阻止计数,直到由于新对象而生成新的签名。
当然,这也会影响性能,所以如果您有更好的想法,请随时回答:p
https://stackoverflow.com/questions/7222995
复制相似问题