$shibayu36->blog;

株式会社はてなでエンジニアをしています。プログラミングや読書のことなどについて書いています。

Mackerelの思想や出来ることを知る - Mackerelサーバ監視実践入門を読んだ

最近Mackerelを触ることが多く、Mackerelで何が出来るのかを知りたいと思い、Mackerelサーバ監視実践入門を読んだ。

Mackerel サーバ監視[実践]入門

Mackerel サーバ監視[実践]入門

この本では、Mackerelにはどのような機能があるのかを広く紹介している。また、実際に使っているユーザの事例もいくつか知ることができる。そのため、Mackerelでサーバを監視したい!と思っている人や、監視をし始めたけどさらにどういうことが出来るのか知りたいと思っている人には非常に参考になりそう。僕も、さらにどういうことが出来るのか知りたいという気持ちだったので、非常に参考になった。

個人的には、この本の内容から、Mackerelはサーバ監視サービスとしてだけではなくて、サーバ管理ツールとして使って欲しいという思いが伝わってきたのが良かった。ただ監視するだけではなくて、ホスト情報の統合管理場所として使い、例えばどのサーバにデプロイするかなどの判断するなどに使うという感じ。このように使うことで、日々サーバの台数が変わるような動的インフラストラクチャの世界でも簡単にホスト一覧やホスト情報を管理することができる。

さて、この本を読んだことで「何ができるか」については知れたものの、ではそれらの機能を使って「どう使うか」というのはまだちゃんと分かっていないと感じた。ただそのへんはまずは自分でいろいろと使ってみるところから始めたいと思った。

読書ノート

  • ロールグラフとは、同じロールに所属するホストが1つのグラフにまとめられたもの 651
  • PagerDuty連携を利用すると、通知先を時間で変更するなど、柔軟なアラート通知ができる 1575
  • メタデータプラグインはホストのメタデータを登録するプラグイン 1742
  • checkプラグインを作るときは、github.com/mackerelio/checkersを使うと便利 1979
  • MackerelはAPIを用いて、「ホスト情報を一元管理する」という思想を推奨している 2531
  • インテグレーションで対応していないクラウド製品との連携は、 2714
    • mkrでホストを作成
    • mkr throwで作成したホストに投稿
    • cronで定期的に送信
    • という方法でできる
  • ホストステータスの自動変更や自動退役 3127
    • mackerel-agentの[host_status]設定でon_start/on_stopを設定することで、ステータスを変更可能
  • mkr pullなどで取得したデータとリモートのデータがずれてないかをCIする 3352
  • 式を使って柔軟なグラフを書く 3371
  • GMOペパボでのMackerel活用事例 3759
    • デプロイ先のホスト一覧をmackerel経由で取得
    • hostsファイルの自動生成
    • 退役忘れホストの自動検知

Scalaのテスト中にJoda-Timeのnowの時刻を固定する

今回はScalaのテストの話。時刻まわりが関わる実装をテストしたい時、テスト中だけ現在時刻を固定したり、現在時刻を過去にしたりなどといったことをやりたいことはよくある。Joda-TimeのDateTime.nowを使って現在時刻を取得している場合、時刻をfakeして固定することが出来たのでメモ。

固定するにはorg.joda.time.DateTimeUtilsのsetCurrentMillisFixedやsetCurrentMillisProviderを利用する。例えば、以下のように時間を固定することができる。

DateTimeUtils.setCurrentMillisFixed(15147648t00000L) // 2018-01-01に固定
println(DateTime.now) // 2018-01-01T09:00:00.000+09:00
DateTimeUtils.setCurrentMillisSystem() // 元に戻す
println(DateTime.now) // 2018-01-23T05:58:51.118+09:00


これだけでやりたいことは出来たのだけど、テスト用にはユーティリティを作っておくと、さらに便利になる。例えば、

import org.joda.time.{ DateTime, DateTimeUtils }
object TimeFaker {
  /**
   * 指定したtimeMillisに時刻を固定する。ブロックを抜けると元に戻る。
   */
  def fake[T](timeMillis: Long)(block: => T): T = {
    DateTimeUtils.setCurrentMillisFixed(timeMillis)
    try {
      block
    } finally {
      DateTimeUtils.setCurrentMillisSystem()
    }
  }

  /**
   * DateTimeオブジェクトを渡せるバージョン
   */
  def fake[T](t: DateTime)(block: => T): T =
    fake(t.getMillis)(block)

  /**
   * ISODateTimeFormatの形式で渡せるバージョン
   * 例) TimeFaker.fake("2018-03-02T12:34:56") { }
   */
  def fake[T](t: String)(block: => T): T =
    fake(DateTime.parse(t).getMillis)(block)
}

fakeを使うとブロック内だけ時刻が固定され、ブロックを抜けるとシステム時間に戻る。またブロック内で返却したものが結果として返ってくる。

// milliSecondsを渡せる
val result = TimeFaker.fake(1515974400000L) {
  println(DateTime.now) // 2018-01-01T09:00:00.000+09:00
  123
}
println(DateTime.now) // 時刻はもとに戻る
println(result) // 123

// DateTimeのオブジェクトを渡せる
val dt = new DateTime(2018, 2, 13, 14, 59)
TimeFaker.fake(dt) {
  println(DateTime.now) // 2018-02-13T14:59:00.000+09:00
}

// ISODateTimeFormatの形式で渡せる
TimeFaker.fake("2018-03-02T12:34:56") {
  println(DateTime.now) // 2018-03-02T12:34:56.000+09:00
}

便利!

ただしDateTimeUtilsを使った書き換えはスレッド共有の空間を書き換えるので、マルチスレッドでテストする時は動かないことに注意しましょう。

gitのcommit日時順にファイル一覧を表示する

レポジトリ内でドキュメントを探している時に、特定ディレクトリの中のファイルをgitのcommit日の順に並べて新しめのファイルを見つけたいなーと思ったことがあったのでやってみた。

例えば https://github.com/golang/go のdoc/以下にある全てのファイルをcommit日時順に一覧してみるには、以下のコマンド一つで良い。

$ git ls-files doc | xargs -I@ bash -c 'echo "$(git log -1 --format="%aI" -- @)" @' | sort -r
2018-01-11T11:30:49-05:00 doc/go1.10.html
2018-01-11T10:41:03-08:00 doc/go_spec.html
2018-01-09T15:32:22-05:00 doc/diagnostics.html
2018-01-09T15:32:22-05:00 doc/debugging_with_gdb.html
2018-01-09T15:26:21-05:00 doc/install-source.html
2018-01-09T15:26:21-05:00 doc/go_faq.html
...

やっていることは

  • git ls-files doc
    • doc以下のファイル一覧を出す
  • xargs -I@ bash -c 'echo "$(git log -1 --format="%aI" -- @)" @'
    • xargsの-Iオプションを使って、ファイル名一つ一つをコマンドに渡す
    • 例えばbash -c 'echo "$(git log -1 --format="%aI" -- doc/go1.10.html)" doc/go1.10.html'のように展開される
  • git log -1 --format="%aI" -- @
    • あるファイルの最新のcommit日時をISO 8601のフォーマットで表示
  • ISO 8601形式なら文字列ソートでも日時順になるのでsort -rする

という感じ。xargs便利。