ことの始まり
正直なところ、この件をまとめたいがためにBlog始めたようなものです。これ書いたらこのBlogは終わるかもしれません。
Splunkでログを集めるにはUniversal Forwarder(UF)と呼ばれるエージェントを導入するのが一番良いわけですが、既に稼働しているシステムに対してエージェントを入れること自体はやはり抵抗があるわけです。というか、抵抗されます。お願いですから抵抗しないでください。
UFの導入が難しい場合は、OSの基本機能などを駆使してSplunkサーバーにログファイルを転送してもらうことになるのですが、Windows環境の場合にはこのあたりの処理をrobocopy使って済ませようと思うことはよくあると思います。便利ですからね、robocopy。つまりrobocopyを使って、Splunkがモニタリングしているフォルダにログファイルを放り込めばいいだけです。
robocopyはWindows2008あたりからしれっとリソースキットの追加なしで使えるようになってますし、ファイルサーバーの移行案件なんかでは必ずといっていいほど登場するメジャーツールですから、お客さんが使いたいと言われてたときも「いいと思います」と返してしまったわけです。
ただ、結論からいうと、robocopy使わないほうがよいです。相性悪すぎです。robocopy使うのをやめてxcopy使いましょう。
なんとも分かりづらい問題でした。
robocopy使うと何がおこるか
robocopyを使用してSplunkがモニタリングしているフォルダにファイル転送していると「あれっ!?」っと思う_timeでインデックスされるときがまれにあります。
現場の画面は貼れないため、ローカルで無理やり再現させたものなので、ちょっと見た目が違うのですが、_timeがログのタイムスタンプと違って1979年になっています(現場では1980年でした)。この状況はログが少ない状況だと見つけやすいですが、それなりのログを放り込んでいるとなかなか気づけません。しかも古すぎるログとして見られてしまうので、DefaultのIndex設定だと、バケットが切り替わる際に捨てられてしまいます。
なぜこのようになるのか調べてみました。
robocopyの動き
robocopyの動きですが、どうやらコピー中はコピー先ファイルのタイムスタンプを1980年1月2日9:00(おそらくJSTに依存して9:00)にしてしまうようです。大きなファイルをrobocopyして、コピーが完了しないうちにファイルのプロバティを開くと以下のようになります。「更新日時」に注目してください。
このような更新日時になるのはコピー中のみのようで、コピーが終わるとrobocopyのオプションに従った更新日時に上書きされます。なぜこのような仕様なのかはよくわかりません。
Splunkの動き
Defautでは、MAX_DAYS_AGOが2000日で、MAX_DAY_HENCEは2日です。これは、2000日より昔のタイムスタンプもしくは2日より未来のタイムスタンプは抽出してくれない事を意味します。MAX_DAYS_AGOの2000日はおよそ5年半なので、稀に古いログを食わせるときにハマります。そして今回のポイントですが、MAX_DAYS_AGOとMAX_DAYS_HENCEは可変なのですが、今回のポイントはいずれの最大値が10951と10950であることです。つまり30年であり、仮に設定を最大値に変更したとしてもファイルの更新日時から30年を超えるタイムスタンプはSplunkは読み込めないという、そんな仕様となっているようです。1980年は今(2018年)から38年の差があるせいでタイムスタンプが抽出できず、ファイルの更新日時をそのまま_timeとして抽出する動きになります。
ちなみに、以下のようなログがsplunkd.logに出力されます。
06-30-2018 22:34:02.644 +0900 WARN DateParserVerbose - Failed to parse timestamp in first MAX_TIMESTAMP_LOOKAHEAD (128) characters of event. Defaulting to timestamp of previous event (Sat Jun 30 16:59:19 2018). Context: source::syslog.nix|host::127.0.0.1|linux_secure|
まとめ
この問題は、robocopyがファイルをコピーしている途中でSplunkがそのファイルを掴んだときに発生するようです。そのため、ファイルサイズの大きいログやネットワーク越しにたらたらコピーしているファイルの場合、発生確率が上がると考えられます。タイミングの問題です。
Splunkからすると、更新日時と30年以上も乖離したタイムスタンプのログがファイル内に存在するなんて想定外、という話のようですし、robocopyにはrobocopyなりの事情があって、1980年の更新日時にしているのではないかと思いますので、結果的には、お互いの相性が悪い、としか言いようがなさそうです。 代替策としては、XCOPYなど、タイムスタンプを変な状態にしないコピーツールになります。ディスクに余裕があれば、robocopy + XCOPYでも良いと思います。WSLが普及したらrsyncを使う時代がくるかもしれません。