Prometheus の JSON を jq で処理する

Prometheus の JSON を jq で処理する

気付き

この作業で得られた気付きを先に書いておく

  • 更新代入 |= についての誤解
    • jq コマンドのパイプ文字 |unixシェルのパイプ文字とは若干イメージが異なる
    • |= は独立のオペレーターで、2つの演算子 |= を組み合わせたものではない
      • 下記の例でも
        • .data.result[].values[] | .[0] |= strflocaltime("%Y-%m-%dT%H:%M:%S%z")
          • これだとvalues[]の2つの要素が出てくる。.[0]のフィルターではなく、|=の結果が出力となる
        • .data.result[].values[] | .[0] | . = strflocaltime("%Y-%m-%dT%H:%M:%S%z")
          • これだとvalues[]の最初の要素しか出てこない。.[0] のフィルターがかかる。
  • フィルターをまとめるにはカッコ () を使う
  • JSONで少し離れた場所の情報は変数に持つ

やりたいこと

  1. unix timeの変換処理
  2. Prometheusでは整数になりそうな数値も整数にならないことがあるので(*)、それを整数に丸める
  3. instance を同時に出力
  4. CSVにする

(*): https://prometheus.io/docs/prometheus/latest/querying/functions/#increase

The increase is extrapolated to cover the full time range as specified in the range vector selector, so that it is possible to get a non-integer result even if a counter increases only by integer increments.

入力

HTTP API /api/v1/query_range の結果がこんなだったとして

{
   "status" : "success",
   "data" : {
      "resultType" : "matrix",
      "result" : [
         {
            "metric" : {
               "__name__" : "foo",
               "job" : "node",
               "instance" : "bar:9100"
            },
            "values" : [
               [ 1689329940, "1.000023" ],
               [ 1689329955, "4.000056" ],
               [ 1689329970, "7.000089" ]
            ]
         },
         {
            "metric" : {
               "__name__" : "foo",
               "job" : "node",
               "instance" : "baz:9100"
            },
            "values" : [
               [ 1689329940, "1.000023" ],
               [ 1689329955, "4.000056" ],
               [ 1689329970, "7.000089" ]
            ]
         }
      ]
   }
}

unix time変換

unix timeを変換。iso8601拡張形式にしようとしたが、微妙に間違っている(タイムゾーンにコロン : がない)。

.data.result[].values[] | .[0] | strflocaltime("%Y-%m-%dT%H:%M:%S%z")

結果

2023-07-14T10:19:00+0000
2023-07-14T10:19:15+0000
2023-07-14T10:19:30+0000
2023-07-14T10:19:00+0000
2023-07-14T10:19:15+0000
2023-07-14T10:19:30+0000

無理やりコロンを挿入。jq の sub() の正規表現で、後方参照は名前付きキャプチャー((?<name>pattern))というものを使って、 "\(.name)" のように参照するそうだ。

.data.result[].values[] | .[0] | strflocaltime("%Y-%m-%dT%H:%M:%S%z") | gsub("(?<a>[+-][0-9][0-9])(?<b>[0-9][0-9])"; "\(.a):\(.b)")

結果

2023-07-14T10:19:00+00:00
2023-07-14T10:19:15+00:00
2023-07-14T10:19:30+00:00
2023-07-14T10:19:00+00:00
2023-07-14T10:19:15+00:00
2023-07-14T10:19:30+00:00

少数を整数に丸め

ダブルクォーテーションが付いているので、数値型にしてから整数にする

.data.result[].values[] | .[1] | tonumber | round

結果

1
4
7
1
4
7

instance を出力する

これは変数に覚えておく

.data.result[] | .metric.instance as $instance | $instance

結果

bar:9100
baz:9100

処理をまとめる

  • jqの場合、これが意外に面倒になる。今回は更新代入 |= を繰り返せば良かったので、比較的、単純
  • strflocaltimeとgsubをカッコでまとめてから代入する
  • tonumberとroundもカッコでくくる
  • 最後に配列にしてCSVにする

(雰囲気で、改行してインデントしてみたけど、何か整形ルールはあるのかな)

.data.result[] |
  .metric.instance as $instance |
  .values[] |
    .[0] |= (strflocaltime("%Y-%m-%dT%H:%M:%S%z") |
             gsub("(?<a>[+-][0-9][0-9])(?<b>[0-9][0-9])"; "\(.a):\(.b)")) |
    .[1] |= (tonumber | round) |
    [.[0], $instance, .[1]] | 
      @csv

結果

"2023-07-14T10:19:00+00:00","bar:9100",1
"2023-07-14T10:19:15+00:00","bar:9100",4
"2023-07-14T10:19:30+00:00","bar:9100",7
"2023-07-14T10:19:00+00:00","baz:9100",1
"2023-07-14T10:19:15+00:00","baz:9100",4
"2023-07-14T10:19:30+00:00","baz:9100",7

お試しURL

これはいつまで有効なんだろう?

Prometheusのグラフで線を追加して、Y軸を調整する

Prometheusのグラフで固定の線を追加して、Y軸を調整する

Grafanaを使えばいいのかもしれないけど、PrometheusのシンプルなGUIも好きかも。

それはそうとして、Prometheusのグラフで、例えば、固定で100(%)の線を追加する場合は、 or vector(100)

node-exporterのCPU使用率のグラフの例

(avg without(cpu) (sum without(mode) (rate(node_cpu_seconds_total{mode!="idle"}[1m]))) * 100) or (vector(100))

Kyrö Gin Tasting Set

Kyrö Gin Tasting Set
  • Kyrö Gin
    • ジェニパー
    • 穀物の甘味
      • もみ殻のような茶色い香り
      • 麦茶
    • ピリピリとした刺激
    • 白木
  • Kyrö Pink Gin
    • 甘い、赤いベリー
  • Kyrö Dark Gin
    • 甘いジェニパー
    • マイルドな舌触り
    • 生姜のような、ピリピリ感
  • Kyrö Whisky
    • 穀物の甘味、麦芽
    • 焦がした麦、麦茶
    • 酸味
    • バナナ様香

少量なので冷凍庫に入れる前にロックで全部飲んでしまった。

Kyrö Gin Tasting Set

GWにKindle Unlimited

Kindle Unlimited が2か月98円のセールだったので、GWのタイミングで申し込んだ。
古い漫画が全巻無料で読めないかなと期待したけど、逆で、古い漫画よりは新作が1巻だけ無料みたいなのが多いみたい。

そんな中でも合本版というのは割と長いものが読める。よくコンビニで売っているやつの電子版になるのかな。

第3巻までしか対象じゃなかった。

これも全3巻のうち2巻までしか読めない。2巻までは面白かったので、それで満足しておく。表紙のリアル気味な感じではないので、作中では主人公はかわいいです。

これは読み応えがあった。全国大会編を最後まで読めた。

ラノベの方。第1巻だけだった。

ビンボー生活の人のまだ読んでないものがあった。

これは何と合本で全13巻、通常の40巻分あります。GWでは読み切れない。

第2巻まで

12巻まで。

Bluetoothが使えなくなった Windows 10

Bluetoothが使えなくなった

  • Windows 10
  • 設定アプリでBluetoothをON/OFFするボタンが表示されない
  • アクションセンターからもBluetoothがなくなる
  • バイスマネージャーからもなくなる
  • インテル ドライバー & サポート・アシスタントで、Wireless Bluetoothが「インストール不明」となっていた
  • 完全シャットダウンというので復旧(Shiftキー押しながらシャットダウン)
  • インテル ドライバー & サポート・アシスタントで、再度ドライバーをインストールしなおし

どうもインテル ドライバー & サポート・アシスタントはトラブルの元になっている気がする

memo

memo

PHSはこのぐらいで速いって喜んでたな。ISDNでも64Kだったっけ?

病気をされてから一層切れ味が増してる

Amazon Fire HD 8

Fire HD 8

2015年のFire HD 8を我慢して使っていたが、買い替えることに。iPad miniにしようかと少し考えたが、寝る前にネットを見るぐらいしか使っていないので、止めておいた。値段が全然違うので。
一回、仕様をメモしておこう。

Fire HD 8 Plus タブレット (2022年発売)

  • ディスプレイ 8インチ HD
  • 解像度 1280 x 800 (189ppi)
  • 重量 342グラム
  • サイズ 201.9 x 137.3 x 9.6 mm
  • RAM 3GB
  • CPU 2.0GHz 6コア
  • 容量 32/64GB
  • バッテリー 最大13時間
  • 充電時間 (同封のアダプター使用時) 約3時間
  • カメラ 2メガピクセルフロントカメラ、5メガピクセルリアカメラ
  • USBポート USB-C (2.0)

Fire HD 8 タブレット 16GB (2015, 第5世代)

  • 解像度 1280 x 800
  • 重量 311グラム
  • サイズ 214 x 128 x 7.7mm
  • RAM 1GB
  • 容量 16GB
  • バッテリー 最大8時間

Kindle Fire HD 16GB タブレット(2012 第2世代)

  • 解像度 1280 x 800
  • 重量 395グラム
  • サイズ 193×137×10.3 mm
  • RAM 1GB
  • 容量 16GB
  • バッテリー 4,400 mAh

正直、ここだけ見ると昔からそんなに変わってない。