"トライアルアンドエラーパイプ"ことfiltで、パイプに繋いだコマンドの実行履歴を保存して次回filt実行時に補完候補として利用できるようにしました
コマンド履歴保存の有効化方法
以下のコマンドを実行することで有効化できます。
$ filt config history.enable true
無効化は
$ filt config history.enable false
です。
コマンド実行を再利用したい人は有効化してみてください
"トライアルアンドエラーパイプ"ことfiltで、パイプに繋いだコマンドの実行履歴を保存して次回filt実行時に補完候補として利用できるようにしました
以下のコマンドを実行することで有効化できます。
$ filt config history.enable true
無効化は
$ filt config history.enable false
です。
コマンド実行を再利用したい人は有効化してみてください
Harvest のログ取得期間指定をより柔軟にできるように --duration
オプションを追加したかったのですが、
time.ParseDuration()
ではあまり柔軟ではないので作りました。
duration.Parse()
は time.ParseDuration()
と同じように利用できます。
time.ParseDuration()
と異なる点は 4hours
や 1minute
などの単位表記も判定できるという点です。
package main import ( "fmt" "github.com/k1LoW/duration" ) func main() { d, _ := duration.Parse("3 days 4 hours") fmt.Printf("%s", d) // Output: 76h0m0s }
これだけです。
--duration
オプションを作りたいときに、ご検討ください。
Consulでちょっとしたヘルスチェックを追加したいと思ったのですが、例えば iowaitが高いかつuserは低いとき
という条件を書こうとしたときに、「うっ。。!どう書けばいいんだ。。」となってしまったので、作りました。
metr
は次のような利用を想定したコマンドです
インストールはHomebrew以外にdeb/rpmパッケージを用意しています。基本的にサーバにコマンドとしてインストールするのが良いでしょう
$ dpkg -i metr_0.5.1-1_amd64.deb
metr list
取得できるメトリクスは metr list
で確認できます。また -p (--pid)
でプロセスのPIDを指定すると、プロセスのメトリクスも対象にできます。
以下はMac上で実行しましたが、Linux上だともう少し取得できるメトリクスが増えます。
$ metr list cpu (now:33.084577 %): Percentage of cpu used. mem (now:66.468358 %): Percentage of RAM used. swap (now:875823104 bytes): Amount of memory that has been swapped out to disk (bytes). user (now:18.610422 %): Percentage of CPU utilization that occurred while executing at the user level. system (now:14.143921 %): Percentage of CPU utilization that occurred while executing at the system level. idle (now:67.245658 %): Percentage of time that CPUs were idle and the system did not have an outstanding disk I/O request. nice (now:0.000000 %): Percentage of CPU utilization that occurred while executing at the user level with nice priority. load1 (now:3.640000 ): Load avarage for 1 minute. load5 (now:4.210000 ): Load avarage for 5 minutes. load15 (now:4.600000 ): Load avarage for 15 minutes. numcpu (now:8 ): Number of logical CPUs. (metric measurement interval: 500 ms) $ metr list -p `pgrep -n docker` proc_cpu (now:1.820857 %): Percentage of the CPU time the process uses. proc_mem (now:1.264739 %): Percentage of the total RAM the process uses. proc_rss (now:217280512 bytes): Non-swapped physical memory the process uses (bytes). proc_vms (now:7010299904 bytes): Amount of virtual memory the process uses (bytes). proc_swap (now:0 bytes): Amount of memory that has been swapped out to disk the process uses (bytes). proc_connections (now:0 ): Amount of connections(TCP, UDP or UNIX) the process uses. cpu (now:22.000000 %): Percentage of cpu used. mem (now:59.768772 %): Percentage of RAM used. swap (now:781451264 bytes): Amount of memory that has been swapped out to disk (bytes). user (now:14.925373 %): Percentage of CPU utilization that occurred while executing at the user level. system (now:6.467662 %): Percentage of CPU utilization that occurred while executing at the system level. idle (now:78.606965 %): Percentage of time that CPUs were idle and the system did not have an outstanding disk I/O request. nice (now:0.000000 %): Percentage of CPU utilization that occurred while executing at the user level with nice priority. load1 (now:1.360000 ): Load avarage for 1 minute. load5 (now:1.610000 ): Load avarage for 5 minutes. load15 (now:1.490000 ): Load avarage for 15 minutes. numcpu (now:8 ): Number of logical CPUs. (metric measurement interval: 500 ms)
metr cond
( alias: metr test
)metr cond
はシェルスクリプトなどでメトリクスを条件に使いたいときなどに利用できます。
metr cond
は test
コマンドと同じように、条件にマッチすると終了ステータス0
、マッチしないと 1
で終了します。
$ metr cond 'cpu < 20 and mem < 50' || somecommand
上記の場合、ホストのCPU使用率が20%以上かホストのメモリ使用率が50%以上のときに somecommand
が実行されます。
ちなみに、利用できるオペレーターは
+
, -
, *
, /
, ==
, !=
, <
, >
, <=
, >=
, not
, and
, or
, !
, &&
, ||
などです。
metr check
metr check
はNagiosプラグインやMackerelのチェック監視 とほぼ同じ終了ステータスの仕様になっています。
終了ステータス | 意味 |
---|---|
0 | OK |
1 | WARNING |
2 | CRITICAL |
3 | UNKNOWN |
$ metr check -w 'cpu > 10 or mem > 50' -c 'cpu > 50 and mem > 90' METR WARNING: w(cpu > 10 or mem > 50) c(cpu > 50 and mem > 90)
上記の場合、ホストのCPU使用率が10%を超えたかメモリ使用率を50%を超えたときに WARNING
(終了ステータス 1
)、CPU使用率が50%を超えた、かつメモリ使用率を90%を超えたときに CRITICAL
(終了ステータス 2
)となります。
簡単にメトリクスを利用したチェックコマンドが作れます。楽したいときなど、是非使ってみてください。
以下、余談です。
metr
の --interval
オプション)RedHatのCustmer Portalの「Vmstat の出力結果はどのように解釈すれば良いですか?」という質問の回答によると
このレポートの最初の行には、コンピューターが最後に再起動してからの平均値が記載されます。
とあります。
procps-ngのvmstatのソースコードをみてみます。値はgetstat関数で取得しているのですが、具体的には /proc/stat
の値を読み取っています。
https://gitlab.com/procps-ng/procps/blob/master/proc/sysinfo.c#L532
そしてmain loopに入る前に1行出力しています。
https://gitlab.com/procps-ng/procps/blob/master/vmstat.c#L306-361
以降はmain loop内で差分をsleep前後の値の差分を利用しています。
つまり、1行目と2行目以降で値の特性が違うということになります。そして大抵欲しいのは2行目以降の値になります。
metr
は上記の(sleepで実現している)時間間隔を -i (--interval)
としてmsで指定できるようにしています(デフォルトは500msです)。
vmstatでもvmstat 1 2 | tail -1
とすれば1秒間隔の差分での計測値を取得することができます。
metr
だともう少し簡単に取得できて、かつ複数のメトリクスで条件などを組みやすいという感じです。
ちなみにmackarel-agentも同じように前後の計測の差分で計測しているようです。
私は先行して、Sheer Heart Attackというデバッグ用ツールを作っています。
両ツールはメトリクスの取得という点では同じなので、今回、 metr
をコアライブラリとしてSheer Heart Attackに組み込むことで実装の共通化もしました。
[BREAKING] Use github.com/k1LoW/metr by k1LoW · Pull Request #21 · k1LoW/sheer-heart-attack · GitHub
metrを拡張していくことでSheer Heart Attackも自動でパワーアップするという寸法です。
いつものように metrics
を短くしただけなんですけど、なんとも読みづらい箇所で省略したなと。。
「メタァ」とか「メトロ」とかで呼んでいます。まあ、呼ぶことはないと思うので大丈夫かな。。
Go Conference ‘19 Summer in Fukuokaでも少し紹介したcolrです。
まずは以下のスクリーンキャストをご覧ください
colr
は tail -F /path/to/access.log
のようなログにカジュアルに色をつけるツールです。
$ tail -F /var/log/nginx/access.log | colr POST GET 404 500 search
のように何個でもカラーにしたい文字列を指定できます。
これだけです
色の指定もできませんし、その他のオプションもありません。 colr
の後に引数としてカラーにしたい文字列を並べるだけです。
実は正規表現っぽい文字列を渡すと正規表現マッチに変更してくれますが、それでも使い方は変わりません。
これだけの機能、ただその分、何も考えずに利用できます。
是非ご利用ください。単純なツールですがなにげに重宝します。
colrが @mattn_jp さんのpatchでWindowsに対応しましたー!
— k1LoW (@k1LoW) 2019年7月16日
ついでにバグもなおしてもらってしまった。。https://t.co/DxTokvfDU4
以下余談です。
grep --color
で色をつけてもパイプで繋ぐと色が消える。その仕組みcolr
の紹介をすると「それ grep --color
でいいんじゃ?」と言われます。「いや、私は絞込みたいわけではないんだよ」となるのですが、今回は別の話です。
例えば
$ tail -F /var/log/nginx/access.log | grep POST --color
とすると POST
に色がつきますが、
$ tail -F /var/log/nginx/access.log | grep POST --color | grep search
とすると POST
の色が消えてしまいます。
ちなみにこれを回避する方法は grep POST --color=always
とすればいいのですが、パイプで繋ぐとなぜ色が消えるのか考えてみました。
ターミナルで色をつける仕組みは特殊なエスケープコードを使って文字列を囲むことで実現しています。
例えば、文字列を赤くするためには以下のような文字列を標準出力に出力します(iTerm2想定)。
fmt.Println("\x1b[31;1mHello, World!\x1b[0m")
ターミナルは、上記エスケープコード付き文字列を「色つけの指示付きの文字列」と解釈してエスケープコード部分を省いて色をつけた形で表示します。
つまり、色をつけているのはターミナルです。
エスケープコードを解釈するのがターミナルでない場合(パイプにつなげたりリダイレクトでファイルに保存する場合)、エスケープコードは「ただの文字列として解釈されてしまう = 不必要な文字列がついている状態」となるわけです。
上記を回避するために grep --color
ではターミナル(擬似端末)かどうかを判断してエスケープコードの出力を制御しているようです。grep --color=always
はその判定処理をスキップしているわけですね。
ちなみに、擬似端末判定処理について、Golangだと github.com/mattn/go-isatty が有名だと思います。
colr
はシンプルに色をつけるためだけのツールです。色をつけなければ何もしないただリソースを消費するだけのコマンドになってしまいます。
なので、「 colr
を利用するときは、どうしても色をつけたいのだろう」と考え、(利用カラーリングライブラリにはターミナル判定処理がついているのですが、)上記の擬似判定処理をスキップしています。
これで、どう使っても色がつくようになりました。
みなさんはdeb/RPMパッケージを作ったことはありますか?
私はtcpdpのパッケージ作成ではじめて作りました。具体的にはここらへんです。
tcpdpはlibpcapに依存していることもあり、DockerでUbuntu/CentOSの環境を作ってその上でコンパイルして、合わせてdeb/RPMパッケージ化までするようにしています。
本来Goはクロスコンパイルができるので、コンパイルしてできたバイナリをdeb/RPMパッケージにできればいいわけです。
ただ、意外にdeb/RPMパッケージをするための前準備が面倒です。
debパッケージであればcontrolファイルを書かないといけないですし、RPMパッケージであればspecファイルを書く必要があります。それぞれ覚えているほど書く機会はないので毎回ググるはめに。
ビルド方法にもお作法があります。これもあまり覚えていませんがディレクトリ構成などいろいろ面倒だった記憶があります。。
いくらワンバイナリとはいえaptやyumで管理できるメリットは大きいので、できればdeb/RPMパッケージも用意したいのですが、上記のような面倒さから億劫になっていました。
ここで見つけたのがNFPMです。
NFPMはGoReleaserのorg配下にあり、GoReleaser( .goreleaser.yml
)からも呼び出せるようになっています。むしろGoReleaser経由の方法を紹介します。
実際にcgrpsの設定を元に説明します。
cgrps/.goreleaser.yml at master · k1LoW/cgrps · GitHub
builds
ディレクティブで id
を付与するまず、builds
ディレクティブでビルド方法を指定すると思いますが、こちらで id
を付与して nfpms
ディレクティブで指定できるようにします。
builds: - id: cgrps-linux 👈 env: - CGO_ENABLED=0 goos: - linux goarch: - amd64
ちょっと古い .goreleaser.yml
の書き方だと id
の指定は必要ありませんが、これの機会に指定しておきましょう。
nfpms
ディレクティブを追加するnfpms
ディレクティブを追加します。
cgrpsでは以下のようにしています。
nfpms: - id: cgrps-nfpms name_template: "{{ .ProjectName }}_{{ .Version }}-1_{{ .Arch }}" builds: - cgrps-linux 👈 homepage: https://github.com/k1LoW/cgrps maintainer: Ken'ichiro Oyama <k1lowxb@gmail.com> description: cgrps is a set of commands for checking cgroups. license: MIT formats: - deb - rpm bindir: /usr/bin epoch: 1
詳しくは GoReleaserのNFPMの設定のドキュメント をご覧ください。
nfpms.builds
には、先ほどの builds.id
を指定します。
UbuntuやCentOSで利用するdeb/RPMパッケージであれば、Linux用にコンパイルする設定を書いた builds.id
を指定することになると思います。
設定は、これで終わりです。
試しに以下のコマンドを実行すると dist/
ディレクトリにdeb/RPMパッケージが作成されていると思います。
$ goreleaser --snapshot --skip-publish --rm-dist
あとはいつものように goreleaser
コマンドを実行することでリリースが完了します。
では実際にNFPMでは何をしているのか気になったので、ソースコードを見てみました。
愚直にspecファイルを書いて、rpmbuildコマンドを叩いていました *1
ある意味安心な実装でしたので、みなさんも是非ご利用ください。
tbls now supports Cloud Spanner !!! https://t.co/TeTg4ulPb6
— k1LoW (@k1LoW) 2019年8月12日
約1,000円の資金を投じて作りました。
1000円超えてた。。。 pic.twitter.com/b60FVMw5V6
— k1LoW (@k1LoW) 2019年8月13日
例えば、 https://github.com/k1LoW/tbls/blob/master/testdata/spanner.sql のSQLで作成したデータベーススキーマから以下のようなドキュメントが生成されます。
https://github.com/k1LoW/tbls/tree/master/sample/spanner
tblsの他のRDBMSと使い方は変わりません。Cloud SpannerのDSNは
spanner://[ProjectID]/[InstanceID]/[databaseID]
となっています。ADCの設定がされていて( gcloud auth application-default login
していて)、データベースへのアクセス権限があれば、もう tbls doc
でのドキュメント生成が可能なはずです。
サービスアカウントのクレデンシャルファイルがあれば、?creds=[GOOGLE_APPLICATION_CREDENTIALS]
をDSNに付与する形での対応も可能です。
$ tbls doc spanner://[ProjectID]/[InstanceID]/[databaseID]?creds=spanner_client_secrets.json
「Cloud SpannerはGCP上にスキーマ情報を確認できるWebUIがあるので特にいらない」となるかと思います。
ただ、以下の点でCloud Spannerの運用にtblsを使うメリットがあると考えています。
.tbls.yml によるコメントの付与は、MySQLやPostgreSQLといったRDBMSにおいては「 ALTER TABLE
する必要なく、コメント運用ができる」というメリットをうたっていましたが、Cloud Spannerにはそもそもテーブルコメント/カラムコメントというものがないようです。
tblsであれば、 .tbls.yml の comments
ディレクティブで各テーブル各カラムコメントを付与して、さらに tbls lint
を使ってCIを回せばコメントの追加漏れがなくなる*1、など、スキーマの長期運用においてメリットがあると考えています。
tblsではINTERLEAVEで親子関係になっているテーブルについて、リレーションがあると判断してその情報をドキュメントに追加します。
INTERLEAVEについては以下のドキュメントをご覧ください。
一方で、何かしらの理由でINTERLEAVEで親子関係にはしていないものの、論理的にはテーブル間に関係があるということはあります。
tblsはそれらについても .tbls.yml の relations
ディレクティブでテーブル間の関係をドキュメントに追加できます。そして tbls lint
を使ったチェックが可能です*2。
これもMySQLやPostgreSQLといったRDBMSにおいては「外部キー制約がないがテーブル間の関係があるということをドキュメント化できる」というようにメリットをうたっていたのですが、Cloud SpannerのINTERLEAVEの特性をみると外部キー制約よりも積極的にインターリーブ しない という選択がありそうなので、「制約はないけど実は関係がある」というような情報を付与するのにtblsはメリットがありそうです。
Amazon Redshiftに続き、Cloud Spannerもちゃんとプロダクションで使ったことがないので是非フィードバックが欲しいと考えています。
既にCloud Spannerをガンガン使っている皆さま、是非使ってみてください。