Parsing 使用scala的日志解析策略
所以昨天我有一个日志文件,在提供的log.txt中有逗号分隔的条目,如下所示:Parsing 使用scala的日志解析策略,parsing,scala,design-patterns,pattern-matching,case-class,Parsing,Scala,Design Patterns,Pattern Matching,Case Class,所以昨天我有一个日志文件,在提供的log.txt中有逗号分隔的条目,如下所示: entry1.1,entry1.2,entry1.3 entry2.1,entry2,2,entry2.3 .......................... line.split match { case Array(entry1,entry2,entry3) => LogEntry(entry1,entry2,entry3) } 因此,我怀着极大的快乐,继续创建了一个案例课程: case clas
entry1.1,entry1.2,entry1.3
entry2.1,entry2,2,entry2.3
..........................
line.split match {
case Array(entry1,entry2,entry3) => LogEntry(entry1,entry2,entry3)
}
因此,我怀着极大的快乐,继续创建了一个案例课程:
case class LogEntry(
entry1:String,
entry2:String,
entry3:String
)
case class LogEntry(
time: java.util.Date,
userId: Int,
host: String,
port: Int
)
并在读取案例类时填充案例类,如下所示:
entry1.1,entry1.2,entry1.3
entry2.1,entry2,2,entry2.3
..........................
line.split match {
case Array(entry1,entry2,entry3) => LogEntry(entry1,entry2,entry3)
}
现在,当我今天运行代码时,问题出现了,我注意到日志条目对象并没有被创建
我查看了今天提供给我的log.txt,意识到条目已更改:
我现在有:
entry1.1,entry1.2,entry1.3,entry1.4
entry2.1,entry2,2,entry2.3,entry2.4
...................................
我现在在每行中都有第四个条目。看起来没什么大不了的,只要用第四个条目(代码味道1)更改我的case类,然后更改模式匹配(代码味道2)
有人能建议我应该如何编写代码来处理这种情况吗。我想扩展我的代码,而不是修改它
谢谢当您想要正确地抽象日志行时,要做的第一件事是给出单个元素的名称和正确的类型,而不是通过名称(即entry1、entry2等)来提供伪索引。因此,我们将有:
case class LogEntry(
time: java.util.Date,
userId: Int,
host: String
)
键入的严格程度取决于您的具体用例(请注意,host
这里不是java.net.InetAddress
)
将新列添加到日志文件时,可能需要保留以下两项:
case class LogEntry(
entry1:String,
entry2:String,
entry3:String
)
case class LogEntry(
time: java.util.Date,
userId: Int,
host: String,
port: Int
)
由于您有名称,您甚至可以更改字段的顺序,旧代码仍然可以工作,因为它期望的字段仍然在这里。因为您不想再处理旧的日志文件,所以只需修改读入代码即可
案例2有点棘手:您必须反映这样一个事实,即在运行的应用程序中有新旧日志条目。您可以:
case class LogEntry(
time: java.util.Date,
userId: Int,
host: String,
port: Option[Int] = None
)
LogEntry=>?
)。还请注意,它可能允许不一致的日志条目(添加两个字段,两个字段都不在格式1中,格式2需要,您仍然可以将其中一个字段设置为None
)
选项2允许调用代码处理条目类型之间的差异。如果高级函数需要一个ExtendedLogEntry
,它的类型将是ExtendedLogEntry=>。
,因此您不能向该函数提供LogEntry
(备选方案:函数中的模式匹配并提供默认/回退行为)。此外,它还防止了选项1可能出现的不一致性
关于读入:选项1将在读取旧式日志文件时自动设置默认参数,在选项2中,旧式日志文件将像以前一样生成
LogEntry
。因此,在这两种情况下,旧的读入代码不需要更改,但可能需要进行调整,以便检测新样式或旧样式日志并生成适当的条目。(请注意,这可能是选项2的一个问题,因为如果不想强制转换,日志的样式将通过键入系统静态强制执行)。如果要在对象中表示日志文件,则可能需要在文件更改时更改对象。您可以始终将内容存储为列表[String]
。文件不应存储为对象,单独的行需要表示为对象,因为它们会进一步推动逻辑的计算。我只想知道日志行条目的适当抽象技术,以便在保持向后兼容性的同时适应文件模式的变化。我不确定将行条目存储为字符串列表会有什么帮助?@sc\u-ray您需要澄清如何处理LogEntry
类。现在我看不出比@bmorris591所建议的使用变长List[String]
有什么好处。变长列表[String]如何映射到数据库表的列?