【发布时间】:2017-05-21 06:18:47
【问题描述】:
我需要解析数百兆字节的应用程序日志,看起来像这样:
2016/05/26 13:07:48 UTC - 15:07:48 Rear gear disengaged
2016/05/26 13:08:13 UTC - 15:08:13 RMCB : Backend in unknown position
2016/05/26 13:08:14 UTC - 15:08:14 OVERPRESSURE ALARM STATUS : no alarm
2016/05/26 13:08:14 UTC - 15:08:14 PRESSURE STATUS : Equipment Off
2016/05/26 13:08:14 UTC - 15:08:14 OVERPRESSURE LINE STATUS : line failure
2016/05/26 13:08:14 UTC - 15:08:14 FILTER EQUIPMENT STATUS : Equipment Off
2016/05/26 13:08:14 UTC - 15:08:14 FILTER LINE STATUS : line failure
2016/05/26 13:08:15 UTC - 15:08:15 RMCB : Backend closed
2016/05/26 13:08:20 UTC - 15:08:20 OVERPRESSURE ALARM STATUS : value=3
2016/05/26 13:08:20 UTC - 15:08:20 OVERPRESSURE ALARM STATUS : alarm Overpressure
2016/05/26 13:08:20 UTC - 15:08:20 PRESSURE STATUS : OK
2016/05/26 13:08:20 UTC - 15:08:20 OVERPRESSURE LINE STATUS : OK
2016/05/26 13:08:20 UTC - 15:08:20 FILTER EQUIPMENT STATUS : OK
2016/05/26 13:08:20 UTC - 15:08:20 FILTER LINE STATUS : OK
2016/05/26 13:08:20 UTC - 15:08:20 [COMMANDER] open wizard view
2016/05/26 13:08:20 UTC - 15:08:20 [DRIVER] open wizard view
2016/05/26 13:08:20 UTC - 15:08:20 [OP2] open wizard view
2016/05/26 13:08:28 UTC - 15:08:28 Acknowledge Alarm : alarm Overpressure
如您所见,它们除了时间戳之外没有任何固定结构,但我需要从它们中获取单独的键/值属性。
例如这一行:
FILTER EQUIPMENT STATUS : OK
这是一个与filter的设备相关的status事件,所以我需要将其解析为以下键/值对:
EventType: Status
SourceContext: FILTER (could also be OVERPRESSURE etc.)
StatusType: EQUIPMENT (could also be LINE)
StatusValue: OK (could also be line failure, if it's a line status)
等等。像这样的一行也是如此:
[COMMANDER] open wizard view
我们有:
EventType: Instruction
Sender: COMMANDER
Instruction: open wizard view
我不需要有数百种不同的类型或其他东西,一个简单的类型,例如固定的事件类型和键/值对字典很好,但我需要找到一种方法来正确识别各个 properties 并将它们映射到所述字典中。
我第一次尝试使用正则表达式捕获组,但除了大量的性能问题之外,我最终得到了数百种不同的模式,其中一些模式非常松散,以至于错误匹配的数量太高了。然后我尝试手动解析它们,在字符串中查找某些指示符(例如包含方括号等),但这会导致巨大的代码墙,其中包含许多特殊情况以及日志事件漏掉或错误发生的可能性已确定。
是否有更适合解决此类问题的模式或技术?
【问题讨论】:
-
首先,this 之类的内容是否符合您的需求?
-
@ThomasAyoub 非常感谢您花时间设置该正则表达式,但不幸的是没有,因为我刚刚发布了完整文件中的日志摘录,还有许多其他可能性如何行可以看和我需要过滤掉的东西。虽然您的正则表达式适用于上面的摘录,但当我根据真实示例对其进行检查时,它错误地捕获了内容。 :(
-
您必须处理多少种不同的日志消息?您可能不得不硬着头皮为不同类型设置几个不同的数据库表并在其中进行搜索。原始消息列,然后是您要将信息拆分成的列。然后,您在 LIKE 语句中搜索日志中的消息,即来自表
PRESSURE STATUS :LIKEPRESSURE STATUS : Equipment Off的消息,然后将其相应地拆分到您的列中。我会尝试找到所有可能的日志并将其放入 Excel 文件中,并将它们分成不同的表以供您的数据库设计... -
@justiceorjustus (据我所知)大约有 2600 种可能性(我将所有日志文件放入脚本中,该脚本分离出重复的行,不包括时间戳)。
-
@artganify Jeez。我以前遇到过这样的事情,也尝试过制作“完美”的算法来将它们分开。这些条件通常最终会互相争斗并给出那些误报。我最终做了类似我上面评论的事情。很抱歉,这条评论没有帮助,似乎有太多变量需要处理。
标签: c# .net regex parsing logging