json 内の文字列で入ってるjsonの中身を書き換える


Overview

何を言ってるのかわからねーと思うが(ry

稀によくある状況

kibana の Visualize でグラフを設定して、これを保存してどこか他のkibanaに移行したい場合、
VisualizeIndex Patterns に紐付いているので、
そのまま他所に投入しても Index Patterns のIDが違うので上手くいかない。

これを jq で書き換えてやる方法。

version

kibana: 6.4.2

とかいいつつ、kibanaが本題ではないんですけど

まぁ細かい話は置いといて、サンプルいきます。

env
export URL_KIBANA=http://localhost:5601
export VISUALIZATION_ID=27248030-3683-11e9-bf8e-47f2e867c71f

visualization のサンプル

curl "${URL_KIBANA}/api/saved_objects/visualization/${VISUALIZATION_ID}"
saved_objects.visualization.json
{
  "id": "27248030-3683-11e9-bf8e-47f2e867c71f",
  "type": "visualization",
  "updated_at": "2019-02-22T09:20:53.683Z",
  "version": 1,
  "attributes": {
    "title": "sample",
    "visState": "{\"title\":\"sample\",\"type\":\"histogram\",\"params\":{\"type\":\"histogram\",\"grid\":{\"categoryLines\":false,\"style\":{\"color\":\"#eee\"}},\"categoryAxes\":[{\"id\":\"CategoryAxis-1\",\"type\":\"category\",\"position\":\"bottom\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\"},\"labels\":{\"show\":true,\"truncate\":100},\"title\":{}}],\"valueAxes\":[{\"id\":\"ValueAxis-1\",\"name\":\"LeftAxis-1\",\"type\":\"value\",\"position\":\"left\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\",\"mode\":\"normal\"},\"labels\":{\"show\":true,\"rotate\":0,\"filter\":false,\"truncate\":100},\"title\":{\"text\":\"Count\"}}],\"seriesParams\":[{\"show\":\"true\",\"type\":\"histogram\",\"mode\":\"stacked\",\"data\":{\"label\":\"Count\",\"id\":\"1\"},\"valueAxis\":\"ValueAxis-1\",\"drawLinesBetweenPoints\":true,\"showCircles\":true}],\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"times\":[],\"addTimeMarker\":false},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}}]}",
    "uiStateJSON": "{}",
    "description": "",
    "version": 1,
    "kibanaSavedObjectMeta": {
      "searchSourceJSON": "{\"index\":\"437ab3b0-3671-11e9-bf8e-47f2e867c71f\",\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"filter\":[]}"
    }
  }
}

これの

  • .attributes.visState
  • .attributes.kibanaSavedObjectMeta.searchSourceJSON

が文字列で入ってる箇所で、

.attributes.visState

jq '.attributes.visState|fromjson' saved_objects.visualization.json
{
  "title": "sample",
  "type": "histogram",
  "params": {
    "type": "histogram",
    "grid": {
      "categoryLines": false,
      "style": {
        "color": "#eee"
      }
    },
    "categoryAxes": [
      {
        "id": "CategoryAxis-1",
        "type": "category",
        "position": "bottom",
        "show": true,
        "style": {},
        "scale": {
          "type": "linear"
        },
        "labels": {
          "show": true,
          "truncate": 100
        },
        "title": {}
      }
    ],
    "valueAxes": [
      {
        "id": "ValueAxis-1",
        "name": "LeftAxis-1",
        "type": "value",
        "position": "left",
        "show": true,
        "style": {},
        "scale": {
          "type": "linear",
          "mode": "normal"
        },
        "labels": {
          "show": true,
          "rotate": 0,
          "filter": false,
          "truncate": 100
        },
        "title": {
          "text": "Count"
        }
      }
    ],
    "seriesParams": [
      {
        "show": "true",
        "type": "histogram",
        "mode": "stacked",
        "data": {
          "label": "Count",
          "id": "1"
        },
        "valueAxis": "ValueAxis-1",
        "drawLinesBetweenPoints": true,
        "showCircles": true
      }
    ],
    "addTooltip": true,
    "addLegend": true,
    "legendPosition": "right",
    "times": [],
    "addTimeMarker": false
  },
  "aggs": [
    {
      "id": "1",
      "enabled": true,
      "type": "count",
      "schema": "metric",
      "params": {}
    }
  ]
}

.attributes.kibanaSavedObjectMeta.searchSourceJSON

jq '.attributes.kibanaSavedObjectMeta.searchSourceJSON|fromjson' saved_objects.visualization.json
{
  "index": "437ab3b0-3671-11e9-bf8e-47f2e867c71f",
  "query": {
    "query": "",
    "language": "lucene"
  },
  "filter": []
}

書き換えたい箇所

このうち、 .attributes.kibanaSavedObjectMeta.searchSourceJSONindex の値を書き換えたい。

なんと jq だけでできるんです。

env
export INDEX_PATTERN_ID=ここを書き換えたい

ややこしいので外部ファイルにします

modify.index_pattern_id.jq
.attributes.kibanaSavedObjectMeta.searchSourceJSON
|= (
  fromjson
  | .index=$ENV.INDEX_PATTERN_ID
  | tojson
)

で、実行すると、

jq -f modify.index_pattern_id.jq saved_objects.visualization.json
{
  "id": "27248030-3683-11e9-bf8e-47f2e867c71f",
  "type": "visualization",
  "updated_at": "2019-02-22T09:20:53.683Z",
  "version": 1,
  "attributes": {
    "title": "sample",
    "visState": "{\"title\":\"sample\",\"type\":\"histogram\",\"params\":{\"type\":\"histogram\",\"grid\":{\"categoryLines\":false,\"style\":{\"color\":\"#eee\"}},\"categoryAxes\":[{\"id\":\"CategoryAxis-1\",\"type\":\"category\",\"position\":\"bottom\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\"},\"labels\":{\"show\":true,\"truncate\":100},\"title\":{}}],\"valueAxes\":[{\"id\":\"ValueAxis-1\",\"name\":\"LeftAxis-1\",\"type\":\"value\",\"position\":\"left\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\",\"mode\":\"normal\"},\"labels\":{\"show\":true,\"rotate\":0,\"filter\":false,\"truncate\":100},\"title\":{\"text\":\"Count\"}}],\"seriesParams\":[{\"show\":\"true\",\"type\":\"histogram\",\"mode\":\"stacked\",\"data\":{\"label\":\"Count\",\"id\":\"1\"},\"valueAxis\":\"ValueAxis-1\",\"drawLinesBetweenPoints\":true,\"showCircles\":true}],\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"times\":[],\"addTimeMarker\":false},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}}]}",
    "uiStateJSON": "{}",
    "description": "",
    "version": 1,
    "kibanaSavedObjectMeta": {
      "searchSourceJSON": "{\"index\":\"ここを書き換えたい\",\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"filter\":[]}"
    }
  }
}

できました。

まぁ 本題は jq なので kibana のjsonとかどうでもいいんですけど。

jq の機能

流れとしては

  • fromjson で文字列をパースして
  • index キーの値を書き換えて
  • tojson で文字列に戻したもので
  • .attributes.kibanaSavedObjectMeta.searchSourceJSON の値を上書き

という感じです。

fromjson tojson

整形中のjsonを文字列にしたり、jsonとして解釈したりしてくれるめっちゃイケてるjqのビルトインです(雑

|=

それ以降に続くコマンドの結果で、対象の値を上書きします。

おわり。

kibana の話はまた別記事で書く。かも。たぶん。