BNFパーサが生成したパーサでパースした後に整形表示してみた

前回BNFパーサーが生成したパーサーでログをパースできるようになりましたので steavevaivai.hatenablog.com

今回はパースした後に整形表示できるようにしてみます。 修正のコミットはこちらになります。
bnfパーサー 整形表示実装 · teruuuuuu/logging_converter@ab5b156 · GitHub

BNFの定義が以下のようになっていたとして

<number> ::= ("0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9")
<date> ::= <number> + "-" <number> + "-" <number> + <sp> <number> + ":" <number> + ":" <number> + "," <number> +
<level> ::= ("DEBUG"|"INFO"|"WARN"|"ERROR"|"FATAL")
<package> ::= <notsp>
<thread> ::= <notsp>
<command> ::= ("add"|"remove"|"set")
<global> ::= ("globalAdd"|"globalRemove")
<move> ::= "move"
<name> ::= ("A"|"B"|"C") ("A"|"B"|"C") ("A"|"B"|"C")
<name1> ::= <name>
<name2> ::= <name>
<point> ::= <number> + "." <number> +
<basiccommand> ::= <date> <sp> <level> <sp> <package> <sp> <thread> <sp> <command> <sp> <name1> ":" <point>
<globalcommand> ::= <date> <sp> <level> <sp> <package> <sp> <thread> <sp> <global> <sp> <point>
<movecommand> ::= <date> <sp> <level> <sp> <package> <sp> <thread> <sp> <move> <sp> "from" <sp> <name1> <sp> "to" <sp> <name2> <sp> ":" <sp> <point>
<root> ::= <basiccommand> | <globalcommand> | <movecommand>

シンボルをobjectのkeyの値として表示することで整形表示できるようにしてみます。以下のように定義しておくと

date: date
command: command,global,move
name1: name1
name2: name2
point: point

objectのdateのkeyの値として、dateのシンボルでパースした結果を使います。同様にcommandのkeyの値にcommandまたはglobalまたはmoveのシンボルのパース結果とするようにします。

これを実現するため、パース結果を文字列から Map[String, List[String]] に変更します。 Mapのkeyをシンボルとして値のList[String]はパース結果の文字列のリストとしています。

これで動かしてみると、以下のように実際にパースできているようでした。

{"point":"25.078","name2":null,"command":"set","date":"2020-05-24 11:30:37,204","name1":"CCC"}
{"point":"83.523","name2":"CBC","command":"move","date":"2020-05-24 11:30:37,204","name1":"CAC"}
{"point":"86.934","name2":"CCA","command":"move","date":"2020-05-24 11:30:37,205","name1":"BCC"}
{"point":"89.417","name2":"AAC","command":"move","date":"2020-05-24 11:30:37,205","name1":"BBA"}
{"point":"77.076","name2":null,"command":"add","date":"2020-05-24 11:30:37,205","name1":"CCC"}
{"point":"76.503","name2":"BCC","command":"move","date":"2020-05-24 11:30:37,205","name1":"CAC"}
{"point":"69.673","name2":"BBA","command":"move","date":"2020-05-24 11:30:37,205","name1":"BBA"}
{"point":"76.516","name2":null,"command":"set","date":"2020-05-24 11:30:37,205","name1":"AAC"}
{"point":"21.810","name2":null,"command":"globalRemove","date":"2020-05-24 11:30:37,205","name1":null}
{"point":"57.912","name2":null,"command":"globalRemove","date":"2020-05-24 11:30:37,205","name1":null}
{"point":"29.730","name2":null,"command":"remove","date":"2020-05-24 11:30:37,205","name1":"CCA"}
{"point":"33.462","name2":null,"command":"globalAdd","date":"2020-05-24 11:30:37,206","name1":null}
{"point":"39.699","name2":null,"command":"add","date":"2020-05-24 11:30:37,206","name1":"CBC"}
{"point":"85.912","name2":null,"command":"add","date":"2020-05-24 11:30:37,206","name1":"ACB"}

Jsonになったので、Elasticsearchに取り込んで検索をしてみました。以前はcontentにログの内容がすべて含まれていたのですが、今回はBNFのシンボル毎で分けて出せているので結果を扱いやすくなったかと思います。

$ curl -XGET -H 'Content-Type: application/json' "localhost:9200/_search?pretty" -d '{
>   "query": { "match_all": {} },
>   "size": 6
> }'
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2359,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "log",
        "_type" : "log",
        "_id" : "CN2_rHIBdNggJPvOgRsW",
        "_score" : 1.0,
        "_source" : {
          "date" : "2020-05-24 11:25:52,497",
          "command" : "globalRemove",
          "point" : "47.772"
        }
      },
      {
        "_index" : "log",
        "_type" : "log",
        "_id" : "Cd2_rHIBdNggJPvOgRsY",
        "_score" : 1.0,
        "_source" : {
          "date" : "2020-05-24 11:25:52,497",
          "command" : "globalAdd",
          "point" : "27.209"
        }
      },
      {
        "_index" : "log",
        "_type" : "log",
        "_id" : "Ct2_rHIBdNggJPvOgRsY",
        "_score" : 1.0,
        "_source" : {
          "date" : "2020-05-24 11:25:52,498",
          "command" : "add",
          "name1" : "ACB",
          "point" : "84.962"
        }
      },
      {
        "_index" : "log",
        "_type" : "log",
        "_id" : "C92_rHIBdNggJPvOgRsY",
        "_score" : 1.0,
        "_source" : {
          "date" : "2020-05-24 11:25:52,498",
          "command" : "globalAdd",
          "point" : "24.738"
        }
      },
      {
        "_index" : "log",
        "_type" : "log",
        "_id" : "DN2_rHIBdNggJPvOgRsY",
        "_score" : 1.0,
        "_source" : {
          "date" : "2020-05-24 11:25:52,498",
          "command" : "globalRemove",
          "point" : "86.972"
        }
      },
      {
        "_index" : "log",
        "_type" : "log",
        "_id" : "Dd2_rHIBdNggJPvOgRsY",
        "_score" : 1.0,
        "_source" : {
          "date" : "2020-05-24 11:25:52,499",
          "command" : "globalRemove",
          "point" : "61.388"
        }
      }
    ]
  }
}