1

I created a process to help me parse log files. The log files need to be tagged with a string tag. Not ever record can provide this string tag, so I need to maintain some state across each log event so that each event will have a tag. If an event is missing a tag, I want to use the last tag found. This allows me to parse logs like below and have a "tag" associated with the message lines even though they are part of eventindex04 record header. I could wrap the event in an envelope and have the logic in the envelope, but then I have an envelope everywhere which seems heavyweight.

eventindex01 start log ...
eventindex02 time ...
eventindex03 user ...
eventindex04 message
  message1
  message2
eventindex05 start log ...

I put together this process which works fine:

def extractStatefulAttribute[T, D](first: T)(getTag: D => Option[T]):
  Process1[D, (T, D)] = {
    def go(lastTag: T): Process1[D, (T, D)] = {
      Process.receive1[D, (T, D)] {
        event: D =>
          val tag = getTag(event) getOrElse lastTag
          Process.emit((tag, event)) ++ go(tag)
      }
    }
   go(first)
}

This feels like it should be expressed as a scan/fold, but I could not make it work. Can this be rewritten as a scan/fold?

user1763729
  • 167
  • 1
  • 11

0 Answers0