Unengineered Weblog

PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND

Mackerel をファイルシステムにした

この記事ははてなエンジニア Advent Calendar 2023の 12月36日 2024年1月5日の記事です。

developer.hatenastaff.com

Mackerel をファイルシステムにしてみましょう。 Mackerel でファイルシステムを監視するのではありません。 Mackerel をファイルシステムにするのです。

じゃん

mackerelfs と言います。よろしくおねがいします。 github.com

/home/rmatsuoka/mackerel ディレクトリに mackerelfs をマウントしましょう(マウントの方法は後半説明します。)最初は ctl ファイルだけがあります。

$ ls -l 
total 0
--w--w--w- 1 rmatsuoka rmatsuoka 0 Jul 14  2042 ctl

さて Mackerel を操作するときは API キーが必要です。 mackerelfs にも API キーを登録しましょう。ここでは私のオーガニゼーション rmatsuoka のものを使います。登録するには ctl ファイルに以下のように書き込むだけです。

$ echo "new $MACKEREL_APIKEY" > ctl

すると mackerel ディレクトリに rmatsuoka というディレクトリが登場しました。

$ ls -l 
total 0
--w--w--w- 1 rmatsuoka rmatsuoka 0 Jul 14  2042 ctl
dr-xr-xr-x 1 rmatsuoka rmatsuoka 0 Jul 14  2042 rmatsuoka
$ ls -1F rmatsuoka/
hosts/
service/

rmatsuoka/hosts 以下にはホストがディレクトリとして一覧になっています。

$ ls -1F rmatsuoka/hosts/
ctl
rmatsuoka-desktop/
Ryuichis-MacBook-Pro.local/

このオーガニゼーションでは私用の端末 rmatsuoka-desktop, Ryuichi-MacBook-Pro.local を監視しています。

rmatsuoka-desktop のメトリック一覧は hosts/rmatsuoka-desktop/metrics を readdir すれば、ファイル(ディレクトリ)として見ることができます。

$ ls -F rmatsuoka/hosts/rmatsuoka-desktop/metrics/
cpu.guest.percentage/
cpu.idle.percentage/
cpu.iowait.percentage/
cpu.irq.percentage/
cpu.nice.percentage/
cpu.softirq.percentage/
cpu.steal.percentage/
cpu.system.percentage/
cpu.user.percentage/
ctl
custom.linux.context_switches.context_switches/
custom.linux.disk.elapsed.iotime_sda/
...

<metric_name>/1hour 以下にあるファイルを読むと過去一時間分のメトリックが取得できます。ホストのカスタムメトリックと同じ形式になっています。

ホストのカスタムメトリックを投稿する - Mackerel ヘルプ

$ cat rmatsuoka/hosts/rmatsuoka-desktop/metrics/cpu.system.percentage/1hour 
cpu.system.percentage   5.542648  1704379920
cpu.system.percentage   5.857077  1704379980
...

metrics/service を readdir しましょう。サービス一覧が見ることができます。このオーガニゼーションには devices というサービスがあります。

$ ls -1F rmatsuoka/service/
ctl 
devices/

devices のロール(ここでは desktop と laptop)とサービスメトリックは rmatsuoka/service/devices 以下にあります。

$ ls -1F rmatsuoka/service/devices/
ctl
desktop/
laptop/
metrics/
$ ls -1F rmatsuoka/service/devices/desktop/
ctl
memo
rmatsuoka-desktop/

ちなみにディレクトリの至るところにある ctl ファイルに reload と write するとそのディレクトリの情報を reload してくれます。

$ echo reload > rmatsuoka/service/devices/ctl

見終わったので、 rmatsuoka オーガニゼーションを mackerelfs から取り除きましょう。mackerelfs のルートにある ctl に書き込むだけです。

$ echo delete rmatsuoka > ctl
$ ls
ctl

ファイルシステムの形をしたアプリケーション

mackerelfs はファイルシステムですが、データを収納するストレージではありません。Mackerel の情報を取得するアプリケーション / インターフェースです。 古くから Unix の「ファイル」とは単にデータの塊を指すだけではなく、デバイスのインターフェースでもありました。今の Unix-like な OS でも /dev 以下にデバイスファイルがありますね。これによってユーザーからはファイルもデバイスopen, read, write など同じ方法で扱うことができます。この考えを更に推し進めた Plan 9 はコンピュータ上のプロセスや、ネットワーク、アプリケーションまで様々なリソースを(ファイルではなく)ファイルシステムとして表現しました。これによって「ネットワークにアクセスする」、「プロセスを見る」といった処理は専用のシステムコールではなく open, read などのファイル用のシステムコールで賄えるようになります。 Linux でもプロセスは /proc 以下にファイルシステムで表現されています。/proc があるおかげで Linux, Plan 9ps コマンドはシンプル(つまり /proc 以下にあるファイルを読むだけ)になっています。一方 /proc がない他の Unix-like では ps コマンドは SUID がついていて強力な権限でゴニョゴニョしている。

mackerelfs は Plan 9 のアプリケーションから着想を得てつくりました。Mackerel のホストやサービスといった情報はファイルにマッピングされ、ユーザーはファイルを操作するシステムコールだけで Mackerel をの情報を取得することができます。

ところでアプリケーションの UI / UX という観点から mackerelfs を見てみましょう。このブログの前半では mackerelfs を使ってみた様子を紹介しました。そこでは lscat, echo のように Unix の基本的なコマンドで完結しています。ファイルシステムなので当然ですね。Unix に慣れた人なら、すぐ使えるのではないかなと思います。 ctl ファイルの挙動は独特ですが。

Mackerel には mkr というCLI アプリケーションがあります。これもシンプルな操作で CLI から Mackerel を操作することができますが、一定程度使い方を学ぶ必要があります。

mackerel.io

さらに mackerelfs は、ファイルIO をつかって簡単にスクリプトを組み、操作を自動化させることができます。コマンドラインで行ったことをそのままスクリプトに書き起こせばよいので、手動と自動の間に連続性があります。また http リクエストができない AWK をつかってスクリプトを組むこともできます。

#!/usr/bin/awk -f

BEGIN {
    while (getline < "rmatsuoka/hosts/rmatsuoka-desktop/metrics/cpu.system.percentage/1hour")) {
        ...
    }
}
...

このようにファイルシステム型のアプリケーションは基本的なコマンドのみで操作が完結したり、自動化しやすかったりの特徴をもっており、使いやすいツールのカタチとしての可能性があると思います。

mackerelfs をマウントする方法

mackerelfs は

func FS() fs.FS

という関数だけが用意されたライブラリです。 fs.FS は Go の標準パッケージ io/fs に定義されたファイルシステムを抽象化したインターフェースです。

pkg.go.dev

fs.FS は標準パッケージの定義ですから、 fs.FS をコンピュータにマウントするサードパーティライブラリはいくつか存在すると思います。 例えば僕が作った ya9p は fs.FS をPlan 9ファイルシステム通信プロトコル 9P2000 によって操作できます。mackerelfs にはこの ya9p を使ったコマンド mackerel9p が用意してあります。

github.com

Linux, macOS などは 9P2000 は 9fans/plan9port にある 9pfuse を使えば FUSE 経由でマウントできます。(macOSFUSE を使うには macFUSE も必要です。)

$ go install github.com/rmatsuoka/mackerelfs/cmd/mackerel9p@latest
$ mackerel9p
$ mkdir mackerel
$ 9pfuse 'tcp!localhost!8000' mackerel

注意事項

  • mackerelfs はこのアドベントカレンダーに向けて大急ぎで作ったので機能が足りてなかったり挙動が不安定です。
  • mackerelfs は私 id:rmatsuoka 個人のプロジェクトとしてつくったプロダクトで、 Mackerel 公式として提供するものではありません。