Java 事件日志解析器的适当设计模式?

Java 事件日志解析器的适当设计模式?,java,logging,Java,Logging,处理解析事件日志的项目,然后根据这些事件的属性更新模型。我一直懒于“完成任务”,更关心前期优化、精益代码和正确的设计模式。主要是自学实验。我感兴趣的是更有经验的设计师认为哪些模式是相关的,或者什么类型的伪编码对象体系结构是最好的、最容易维护的,等等 单个日志中可能有500000个事件,大约有60种类型的事件,所有这些事件共享大约7个基本属性,然后根据事件类型增加0到15个属性。事件类型是每行日志文件中的第二个属性 因此,我尝试了一个非常难看的命令式解析器,它逐行遍历日志,然后逐行处理事件。然后我

处理解析事件日志的项目,然后根据这些事件的属性更新模型。我一直懒于“完成任务”,更关心前期优化、精益代码和正确的设计模式。主要是自学实验。我感兴趣的是更有经验的设计师认为哪些模式是相关的,或者什么类型的伪编码对象体系结构是最好的、最容易维护的,等等

单个日志中可能有500000个事件,大约有60种类型的事件,所有这些事件共享大约7个基本属性,然后根据事件类型增加0到15个属性。事件类型是每行日志文件中的第二个属性

因此,我尝试了一个非常难看的命令式解析器,它逐行遍历日志,然后逐行处理事件。然后我尝试了一个使用“nextEvent”模式的词汇规范,该模式在循环中调用并处理。然后,我尝试了一个简单的老“parse”方法,它从不返回,只是向注册的侦听器回调触发事件。无论事件类型如何,我都尝试了一个回调函数,也尝试了一个特定于每个事件类型的回调函数

我尝试了一个包含所有可能属性的并集的基本“事件”类。我试图避免使用“newevent”调用(因为可能会有大量的事件,并且事件对象通常是短期的),并且每个类型都有回调方法和基本属性参数。我已经尝试为60种事件类型中的每一种类型创建一个子类,该子类有一个抽象事件父类,父类有7个公共基属性

最近,我尝试更进一步,使用命令模式将事件处理代码放在每个事件类型中。我不确定我是否喜欢这种方法,它与每种类型的回调方法非常相似,只是代码在类型子类中的执行函数中,而不是每种类型的回调方法


问题是很多模型更新逻辑都是共享的,而且很多都是特定于子类的,我刚刚开始对整个事情感到困惑。我希望有人能至少给我一个考虑的方向! 可能(如果你能在网上找到一个很好的解释-他们似乎缺乏。)

考虑一个战略对象的Flyweight工厂,每类事件一个


对于每一行事件数据,从flyweight工厂中查找适当的解析策略,然后将事件数据传递给策略进行解析。60个strategy对象中的每一个都可以属于同一个类,但配置了不同的字段解析对象组合。如果没有更多的细节,就很难更具体一些。

嗯。。。首先,在一个变化如此之大的场景中,我倾向于使用一个使用属性包(dictionary、hashtable、w/e floats your boat)存储事件信息的单个事件类,而不是一个包含所有属性的并集的单个事件类,或者61个事件类(1个base、60个sub)。事件的类型只是放入包中的另一个属性值。我倾向于这样做的主要原因是我不愿意维护60个派生类

最大的问题是。。。在处理事件时,您与事件有什么关系。您是否将它们格式化为报告,将它们组织到数据库表中,在发生某些事件时唤醒人们。。。什么


这是一个事后解析器,还是一个实时事件处理程序?我的意思是,您是在事件发生时监视日志,还是在第二天解析日志文件?

我不确定是否正确理解了这个问题。我假设存在一个复杂的“模型更新逻辑”。不要通过60个类来分发它,将它放在一个地方,将它从事件类中移出(中介模式,类似于)

您的中介将使用事件类(我不知道您如何在这里使用Flyweight),事件可以自行解析

如果更新规则非常复杂,那么用通用编程语言就无法真正解决这个问题。考虑使用基于规则的引擎或类似的东西。 就在顶部:

我喜欢被接受的答案中关于只有一个类具有属性映射的建议。我还认为behvavior也可以这样组装:

class Event
{
    // maps property name to property value
    private Map<String, String> properties;

    // maps property name to model updater
    private Map<String, ModelUpdater> updaters; 

    public void update(Model modelToUpdate)
    {
        foreach(String key in this.properties.keys)
        {
            ModelUpdater updater = this.updaters[key];
            String propertyValue = this.properties[key];

            updaters.updateModelUsingValue(model, propertyValue);
        }
    }

}
EventFactory从文件构造事件。它根据事件的属性填充两个映射。这意味着有某种方法可以将属性与其关联的模型更新程序相匹配


我没有任何花哨的图案名称给你。如果您有一些复杂的规则,比如如果事件具有属性A、B和C,那么忽略B的模型更新程序,那么必须以某种方式扩展这种方法。最可能的情况是,您可能需要以某种方式使用规则对象模式将一些规则注入EventFactory。好了,有一个图案名称给你

嗯,我非常确定我想坚持使用基本体作为事件属性,因为它们是已知的、不变的,而且我非常关心性能。我想生成一个关于事件块聚合信息的报告。事实上,但我想按顺序(确定地?)处理。解析器组件已经完成,它是一个有限状态机,可以很好地处理所有事件。对不起,我不清楚。问题是我不知道在解析之后如何处理事件。我最终使用了类似这样的方法以及属性包方法。我基本上只是提取事件类型作为包的第二个属性,并将处理程序附加到60个不同的类型。谢谢你的正式推荐。
Model someModel;

foreach(line in logFile)
{
    Event e = EventFactory.createFrom(line);
    e.update(someModel);
}