ようへいの日々精進XP

よかろうもん

2020 年 05 月 06 日 (水)

アクティビティ (今までの走行 (歩行) 距離)

https://pixe.la/v1/users/inokappa/graphs/fitbit-activity

Fitibit Charge2 のアクティビティから走行 (歩行) 距離を Fitbit Web API で取得して Pixela で草生やしている. 色が濃くなれば濃くなる程強度が高い (歩行, 走行距離が長い) ということで. 実装の詳細はこちら.

ジョギング

  • 引き続き, 完全休養
  • 引き続き, 安静にしておく
  • 今日も山王公園を奥さんと散歩

ギョーム

ギョームじゃないけど, 以前から作りたかった Packer の Post Processor プラグインを作った.

github.com

名前は長いけど, EC2 の Launch Template に設定されている AMI を更新する Post Processor プラグインです.

夕飯

  • 奥さんが作った味噌を付けて焼いたサワラが美味しゅうございました

2020 年 05 月 05 日 (🔥)

アクティビティ (今までの走行 (歩行) 距離)

https://pixe.la/v1/users/inokappa/graphs/fitbit-activity

Fitibit Charge2 のアクティビティから走行 (歩行) 距離を Fitbit Web API で取得して Pixela で草生やしている. 色が濃くなれば濃くなる程強度が高い (歩行, 走行距離が長い) ということで. 実装の詳細はこちら.

ジョギング

  • 引き続き, 完全休養
  • 引き続き, 安静にしておく
  • 山王公園を奥さんと散歩

ギョーム

  • 昨日作った Vagrant Plugin があんまり意味のないものだったので, 改めてブログを書いた

inokara.hateblo.jp

とは言え, mitamae 向けのプラグインも作ってみた.

github.com

Vagrant で抽象化出来るという意味では作る意味はあったのかなって自分を慰めている.

夕飯

  • 手羽元の赤ワイン煮込みが美味しかったし, カボチャのサラダもカボチャの味をしっかりと味わえて良かった

vagrant で同じタイプの Provisioner を複数利用する方法 〜 ちゃんとドキュメントを読みましょう案件 〜

tl;dr

昨日, 以下のようなブロクを認めました. また, vagrant から goss というコマンドラインツールを実行出来るプラグインを作ってみました.

inokara.hateblo.jp

github.com

このプラグインを作ったのは, shell provisioner から実行していた goss を個別に実行したかったからということが理由の一つでした.

  config.vm.provision :shell, inline: <<~BASH
    sudo yum install -y wget httpd && \
     goss --gossfile spec/goss.yaml --vars node.yml validate --format documentation 
  BASH

これを,

  config.vm.provision :shell, inline: <<~BASH
    sudo yum install -y wget httpd && \
  BASH

  config.vm.provision :goss do |goss|
    goss.root_path = '/vagrant'
    goss.spec_file = '/spec/goss.yaml'
    goss.vars_file = '/node.yml'
    goss.goss_path = '/bin/goss'
  end

このように書けば, 以下のように実行出来ることを期待していました.

$ vagrant provision --provision-with=shell # こっちで wget と Apache のインストール
$ vagrant provision --provision-with=goss # こっちで goss の実行

実際に, 上記のように期待する動作を得ることが出来ましたが... なんかモヤモヤした気持ちが残っていました.

モヤモヤ

vagrant のようなプロダクトが

同じ provisioner タイプを複数実行出来ないはずがない.

という気持ちで眠れずに改めてドキュメントを読んでみました.

Basic Usage

ドキュメントの Basic Usage に明記されていました.

www.vagrantup.com

以下, provisioner の基本形です.

Vagrant.configure("2") do |config|
  config.vm.provision "bootstrap", type: "shell", run: "never" do |s|
    s.inline = "echo hello"
  end
end

config.vm.provision のオプションとして, name, type, そして, before, after が指定可能です. 上記のサンプルコードだと, 以下のような値が設定されていることになります.

  • name = bootstrap
  • type = shell

The --provision-with flag can be used if you only want to run a specific provisioner if you have multiple provisioners specified. For example, if you have a shell and Puppet provisioner and only want to run the shell one, you can do vagrant provision --provision-with shell. The arguments to --provision-with can be the provisioner type (such as "shell") or the provisioner name (such as "bootstrap" from above).

上記はドキュメントの一部を抜粋したものですが, --provision-with パラメータの値として指定するのは, name の値を指定する旨, 記載されています. ちなみに, --provision-with パラメータには name 及び type を指定することが可能なようです.

$ vagrant provision --help
Usage: vagrant provision [vm-name] [--provision-with x,y,z]
        --provision-with x,y,z       Enable only certain provisioners, by type or by name.
    -h, --help                       Print this help

やっぱり...

プラグイン作るまでもなかったようです... ということで, 以下のような Vagrantfile を書いて試してみました.

Vagrant.configure('2') do |config|
  config.vm.box = 'centos/7'

  config.vm.provider "virtualbox" do |vb|
     vb.memory = '512'
  end  

  config.vm.provision 'mitamae', type: 'shell' do |s|
    s.inline = <<~BASH
      echo 'Run mitamae!!!'
    BASH
  end

  config.vm.provision 'goss', type: 'shell' do |s|
    s.inline = <<~BASH
      echo 'Run goss!!!'
    BASH
  end
end

以下のように, --provision-withmitamaegoss を切り替えて実行可能なことが確認出来ました.

f:id:inokara:20200505102603g:plain

ということで

ドキュメントはちゃんと読もう案件でした. 昨日作ったプラグインプラグインで細々と育てていこうと思います.

おつかれ, 昨日の自分.

2020 年 05 月 04 日 (🌙)

アクティビティ (今までの走行 (歩行) 距離)

https://pixe.la/v1/users/inokappa/graphs/fitbit-activity

Fitibit Charge2 のアクティビティから走行 (歩行) 距離を Fitbit Web API で取得して Pixela で草生やしている. 色が濃くなれば濃くなる程強度が高い (歩行, 走行距離が長い) ということで. 実装の詳細はこちら.

ジョギング

  • 引き続き, 完全休養
  • 引き続き, 安静にしておく
  • 山王公園を散歩

ギョーム

inokara.hateblo.jp

夕飯

  • ジャコと新キャベツのペペロンチーノを作った
  • 帆立のバター焼きも作ったけど, サクッと作った割には美味しゅうございました

ステイホームなゴールデンウィークなので Vagrant で goss を実行出来るプラグインを作ってみた

tl;dr

皆さん, ステイホームしてますか.

ちょっと前に久しぶりに EC2 のカスタム AMI を作成するにあたって, Vagrant + vagrant-ec2 + mitamae + goss という組み合わせで実装したりテストをしていました. mitamae でレシピを流して, goss でテストをするという流れです.

github.com

github.com

mitamae も goss も VagrantShell Provisioner で以下のように実行することが出来るのですが, 以下のように goss だけ走らせたい時に面倒だなあという思いがあり Vagrant Plugin 実装の勉強も兼ねて Provisioner プラグインを作ってみました.

$ vagrant provision --provision-with=goss

vagrant-plugin-goss

リポジトリ

github.com

Vagrantfile

goss は Golang で書かれている為, ワンバイナリ化されています. これをダウンロードする為に wget コマンドは必須です.

Vagrant.configure('2') do |config|
  config.vm.box = 'centos/7'

  config.vm.provider "virtualbox" do |vb|
     vb.memory = '512'
  end  

  config.vm.synced_folder '.', '/vagrant',
    disabled: false,
    type: 'rsync',
    rsync__exclude: [
      '.envrc',
      '.ruby-version',
      '.env',
      './tmp/',
      './bk/'
    ]
  config.vm.provision :shell, inline: <<~BASH
    sudo yum install -y wget httpd
  BASH

  config.vm.provision :goss do |goss|
    goss.root_path = '/vagrant'
    # root_path からの絶対パスで指定する #{root_path}/foo/bar であれば, /foo/bar と指定
    goss.spec_file = '/spec/goss.yaml'
    # root_path からの絶対パスで指定する #{root_path}/baz であれば, /baz と指定
    # goss.vars_file = '/vars.yaml'
    # root_path からの絶対パスで指定する #{root_path}/foo/bar であれば, /foo/bar と指定
    goss.goss_path = '/goss'
    # goss の output format を指定する, デフォルトは documentation, junit, json, nagios, rspecish, tap, silent
    # goss.output_format = 'junit'
  end
end

後は, 任意のディレクトリに goss が利用する YAML ファイル (--gossfile オプションで指定するファイル) を用意します.

$ mkdir spec
$ cat << EOF > ./spec/goss.yaml
package:
  httpd:
    installed: true
  wget:
    installed: true
EOF

後は, vagrant up からの vagrant provisionvagrant rsync からの vagrant provision 等, 素敵な vagrant 生活をお送り下さい.

f:id:inokara:20200504164943g:plain

vagrant-plugin-goss 前夜

ちなみに, vagrant-plugin-goss を作る前は, 以下のように Shell Provisioner を書いておりました.

  config.vm.provision :shell, inline: <<~BASH
    cd /vagrant && \
    ./bin/depend.sh && \
    ./bin/mitamae local bootstrap.rb --node-yaml=node.yml #{args}
    ./bin/goss --gossfile spec/goss.yaml --vars node.yml validate --format documentation 
  BASH

この状態で mitamae だけ, goss だけ実行したい場合, いちいち該当行以外をコメントアウトしていました.

Vagrant Plugin の実装について

以下は

このプラグインを作っていく上で学んだことなどを書きます. あくまでも自分の主観で書いているので, 用語の使い方等に誤りがあるかもしれませんがご容赦下さい.

参考

以下のドキュメントや Github リポジトリを参考にしました.

github.com

github.com

www.vagrantup.com

www.vagrantup.com

www.vagrantup.com

plugin.rb が起点になる

以下は lib/vagrant-goss/plugin.rb の抜粋です.

module VagrantPlugins
  module Goss
    class Plugin < Vagrant.plugin('2')
      name 'goss'
      description <<-DESC
      This plugin executes a goss suite against a running Vagrant instance.
      DESC

      config(:goss, :provisioner) do
        require_relative 'config'
        Config
      end

      provisioner(:goss) do
        require_relative 'provisioner'
        Provisioner
      end
    end
  end
end

プラグインにとって, ここが起点になり, 今回は Provisioner プラグインとなるので, configprovisioner のブロックを定義します. 個々のブロックで require_relative の引数に指定している configprovisioner をコツコツと書いていくことになります.

ちなみに configprovisioner 以外にも command 等も用意されています. commandについては,vagrant xxxx` と実行する際に実行されるコマンド等を定義出来るのかなーと予想しています.

config.rb

以下は lib/vagrant-goss/config.rb の抜粋です.

module VagrantPlugins
  module Goss
    class Config < Vagrant.plugin('2', :config)
      attr_accessor :output_format
      attr_accessor :spec_file
... 略 ...
      def initialize
        super
        @output_format = UNSET_VALUE
        @spec_file = UNSET_VALUE
... 略 ...
      def finalize!
        @output_format = 'documentation' if @output_format == UNSET_VALUE
        @spec_file = 'goss.yaml' if @spec_file == UNSET_VALUE
 ... 略 ...

attr_accessor しているのは, Vagrantfile で以下のように (goss.root_path とか) 書くためですよね. (多分

  config.vm.provision :goss do |goss|
    goss.root_path = '/vagrant'
    # root_path からの絶対パスで指定する #{root_path}/foo/bar であれば, /foo/bar と指定
    goss.spec_file = '/spec/goss.yaml'
... 略 ...

provisioner.rb

以下は lib/vagrant-goss/provisioner.rb の抜粋です.

... 略 ...
module VagrantPlugins
  module Goss
    class Provisioner < Vagrant.plugin('2', :provisioner)
... 略 ...
      def provision
        vars_option = "--vars #{@vars_file} " unless @vars_file.nil?
        run = "#{@goss_path} --gossfile #{@spec_file} " +
              "#{vars_option} " +
              "validate " +
              "--format #{@output_format} --color" 
        run_command(run) if download_goss(@goss_path)
      end 

goss 実行時の出力を Vagrant 標準の出力 (以下のように, 標準出力の場合には緑で表示されたり, default: が行頭につくようにする) にする為に試行錯誤しました.

f:id:inokara:20200504163530p:plain

結局, Vagrant Shell Provisioner のソースコードを参考 (そのまま利用) させて頂きました. 以下の部分です.

      # refer to: https://github.com/hashicorp/vagrant/blob/master/plugins/provisioners/shell/provisioner.rb#L67-L81
      def handle_comm(type, data)
        if [:stderr, :stdout].include?(type)
          # Output the data with the proper color based on the stream.
          color = type == :stdout ? :green : :red

          # Clear out the newline since we add one
          data = data.chomp
          return if data.empty?

          options = {}
          options[:color] = color if !config.keep_color

          machine.ui.detail(data.chomp, options)
        end
      end

ドキュメントにも書かれていました.

Most plugins are likely going to want to do some sort of input/output. Plugins should never use Ruby's built-in puts or gets style methods. Instead, all input/output should go through some sort of Vagrant UI object. The Vagrant UI object properly handles cases where there is no TTY, output pipes are closed, there is no input pipe, etc.

  • puts 等の Ruby 標準の入出力メソッドは使ってはいけない
  • 代わりに Vagrant が提供している UI オブジェクトを利用する必要がある
  • UI オブジェクトは ui プロパティを介して, すべての Vagrant::Environment で使用することが出来る

以上

ステイホームで素敵なインフラストラクチャアズコードな生活をお送り下さい.

2020 年 05 月 03 日 (🌅)

アクティビティ (今までの走行 (歩行) 距離)

https://pixe.la/v1/users/inokappa/graphs/fitbit-activity

Fitibit Charge2 のアクティビティから走行 (歩行) 距離を Fitbit Web API で取得して Pixela で草生やしている. 色が濃くなれば濃くなる程強度が高い (歩行, 走行距離が長い) ということで. 実装の詳細はこちら.

ジョギング

  • 引き続き, 完全休養
  • 引き続き, 安静にしておく

ギョーム

夕飯

  • 奥さん初挑戦の手羽の甘辛炒め, とても美味しかった

シュッとグラフ画像が欲しい時に image-charts.com を使ったら助かったのでメモ

tl;dr

ある数値を集計して円グラフを描いてその画像を Slack に貼り付けたいなあと調べていたら image-charts.com なるサービスが提供されていたので利用してみました.

www.image-charts.com

Google Chart API も選択肢として検討しましたが, 画像を S3 バケットに保存したかったり, Node.js から利用したかったりという要件に合わなかった (探せていないだけかもしれませんが) 為, 今回は image-charts.com を利用することにしました.

developers.google.com

image-charts.com

API でグラフを生成することが出来る

image-charts.com のトップページに以下のように記載されています.

No need to spend hours to setup and develop a complex server-side solution. We spent months tuning our chart API generation infrastructure so you don't have to. One API call url = one chart.

スーパーざっくりと申し上げると, 簡単に REST API を利用してグラフイメージを生成することが出来るサービスです.

例えば, 以下のように curl を利用してリクエストを送信することで...

$ curl -s 'https://image-charts.com/chart?cht=p3&chs=700x100&chd=t:60,40&chl=Hello|World&chf=ps0-0,lg,45,ffeb3b,0.2,f44336,1|ps0-1,lg,45,8bc34a,0.2,009688,1' -o helloworld.png

helloworld.png を開くと以下のような円グラフ画像が生成されます.

f:id:inokara:20200503154036p:plain

また, パラメータに &chan を付与してリクエストを送信すると...

$ curl -s 'https://image-charts.com/chart?cht=p3&chs=700x100&chd=t:60,40&chl=Hello|World&chf=ps0-0,lg,45,ffeb3b,0.2,f44336,1|ps0-1,lg,45,8bc34a,0.2,009688,1&chan' -o helloworld.gif

以下のように GIF アニメーションの円グラフ画像が生成されます.

f:id:inokara:20200503154249g:plain

パラメータ

描画するグラフのタイプやサイズ, 出力のフォーマット (デフォルトは PNG) 等設定可能なパラメータが非常に多いです.

documentation.image-charts.com

詳細はドキュメントをご確認いただければと思いますが, 先述の円グラフリクエストに付与しているパラメータについて書きます.

パラメータ 用途 サンプル値
cht グラフのタイプ指定 (bvs = バー, p = 円, ls = 折れ線) p3
chs 出力する画像サイズ指定 700x100
chd データフォーマット指定 t:60,40
chl グラフラベル指定 Hello|World
chf グラフの塗りつぶし指定 ps0-0,lg,45,ffeb3b,0.2,f44336,1|ps0-1,lg,45,8bc34a,0.2,009688,1
chn GIF アニメーションで出力する

以下のように image-charts.com のサイト上で, 実際にパラメータを調整しながらグラフ画像を確認することが可能です.

f:id:inokara:20200503160659p:plain

Node.js から利用する

Image Charts Node.js Library

以下のように npm で提供されているので, yarn add image-charts 等で自身のプロジェクトに追加しましょう.

www.npmjs.com

雑なサンプルコード

Node.js (JavaScript) も Hello World な身分で恐縮ですが, 以下のような円グラフを描画するサンプルスクリプトを書きました.

const imageCharts = require('image-charts')({});
const fs = require("fs");

const buildGraphArgs = (graphData) => {
    let imageArgs = {};
    let datas = [];
    let labels = [];
    let legendLabels = [];
    const total = graphData.total
    let counts = 0;
    for (let i in graphData.values) {
        counts += graphData.values[i].count;
        percent = Math.round(graphData.values[i].count / total * 100);
        datas.push(percent);
        labels.push(percent + '%');
        legendLabels.push(graphData.values[i].name);
    }
    const others = Math.round((total - counts) / total * 100);
    datas.push(others);
    labels.push(others + '%');
    legendLabels.push('others');

    return {
      title: 'Percentage of Total', 
      size: [ 500, 300 ], 
      data: datas,
      labels: labels,
      legendLables: legendLabels
    };
};

// ここはサンプルを拝借
const buildImage = async (imageArgs) => {
    const pieChart = imageCharts.pie(imageArgs);
 
    try {
        const b = await pieChart.buffer();
        return b;
    } catch (err) {
        return Promise.reject(err);
    }
};

const main = async () => {
    graphData = {
      total: 100,
      values: [
        { name: 'aa', count: 30 },
        { name: 'bb', count: 18 },
        { name: 'cc', count: 12 },
      ]
    };

    imageArgs = buildGraphArgs(graphData);
    imageData = await buildImage(imageArgs);
    fs.writeFile('sample.png', imageData, (err) => {
      if (err) throw err;
      console.log('Image written successfully.');
    });
}

main();

実行すると, 以下のように出力されるだけですが...

$ node sample.js
Image written successfully.

同じディレクトリに sample.png というファイルが生成されるので開いてみます.

$ open sample.png

以下のような円グラフ画像が生成されています.

f:id:inokara:20200503170105p:plain

良い感じです.

円グラフ以外にも...

棒グラフの場合には, 以下のように書きます.

const buildGraphArgs = (graphData) => {
... 略...
    legendLabels.unshift('0:');

    return {
      title: 'Percentage of Total', 
      size: [ 500, 300 ], 
      data: datas,
      labels: labels,
      axis: [ 'x', 'y' ],
      axisLabels: [ legendLabels ]
    };
};

const buildImage = async (imageArgs) => {
    const barChart = imageCharts.bar(imageArgs);
 
    try {
        const b = await barChart.buffer();
        return b;
    } catch (err) {
        return Promise.reject(err);
    }
};

X 軸, Y 軸にラベルを付与するパラメータを付与して imageCharts.bar() を呼び出します.

以下のような棒グラブの画像が生成されました.

f:id:inokara:20200503173852p:plain

ついでに GIF アニメーションも生成してみました.

f:id:inokara:20200503174956g:plain

GIF アニメーションを生成する場合, パラメータは以下のようなパラメータを付与します.

... 略 ...
    return {
      title: 'Percentage of Total', 
      size: [ 500, 300 ], 
      data: datas,
      labels: labels,
      axis: [ 'x', 'y' ],
      axisLabels: [ legendLabels ],
      animation: ['1200','easeOutBack'],
      format: '.gif'
    };

以上

シュッと

image-charts.com を Node.js から使ってみたメモでした. ライブラリ自体は初心者の自分でも何となく雰囲気を掴むことが出来, コードやテストコードを読みながら試行錯誤することが出来ました.

他にも似たようなサービスがあるのかもしれませんが, シュッとグラフ画像を作成して Slack に張りたい場合等に利用を検討したいなあと思います.

ちなみに, おいくら万円?

www.image-charts.com

image-charts.com では, 以下のように, Developer プラン, Enterprise プラン, Enterprise+ プランが提供されています.

f:id:inokara:20200503223416p:plain

Docker イメージによるオンプレミス環境での利用も可能 (Enterprise プラン以上) です.

2020 年 05 月 02 日 (土)

アクティビティ (今までの走行 (歩行) 距離)

https://pixe.la/v1/users/inokappa/graphs/fitbit-activity

Fitibit Charge2 のアクティビティから走行 (歩行) 距離を Fitbit Web API で取得して Pixela で草生やしている. 色が濃くなれば濃くなる程強度が高い (歩行, 走行距離が長い) ということで. 実装の詳細はこちら.

ジョギング

  • 引き続き, 完全休養
  • 引き続き, 安静にしておく
  • 久しぶりに山王公園で散歩 with 奥さん

ギョーム

  • お休みだけど, ギョーム半分, 趣味半分で DDoS 検知の仕組みを作ったりした

夕飯

  • おろしハンバーグ, 昨晩の残りものだったけど美味しかったし, 大根おろし山盛りで有り難かった

Elasticsearch 上のデータを割と簡単にダンプして他の Elasticsearch にインポート出来る elasticsearch-dump を使ってみた

ti;dr

VPC 内で動いている Amazon Elasticsearch Service (以後, AES) 上の一部のインデックスデータを手元の端末の Elasticsearch でも利用したいと思った時に散々悩んで調査した結果, 以下のようなツールが OSS で提供されていたので使ってみましたのでメモです.

github.com

本来ならば, Logstash を使ったりするのが順当なところなのかもしれませんが, mysqldump みたいなカジュアル利用出来るので気持ち良かったです.

taskrabbit/elasticsearch-dump

セットアップ

github.com

Node.js で実装されていて, npm install でインストールするか, Docker イメージが配布されています.

今回は, Amazon Elasticsearch Service からデータをダンプする環境では Docker イメージを利用しました.

$ docker pull taskrabbit/elasticsearch-dump

ダンプされたデータをインポートする環境では npm install でインストールしました.

$ npm install elasticdump

使い方

詳細は README をご一読頂ければと思いますが, とてもシンプルに使い始めることが出来ると思います. 以下はドキュメントより引用させて頂きました.

elasticdump \
  --input=http://production.es.com:9200/my_index \
  --output=http://staging.es.com:9200/my_index \
  --type=data
  • --input はソースとなる Elasticsearch インデックスのエンドポイント
  • --output はデータをインポートする Elasticsearch インデックスのエンドポイント
  • --type では data を指定するとデータ (Document) そのもの, --mapping を指定すると, その名の通りマッピングもインポートが可能

試しにヘルプを確認してみましたが, かなり多くのオプションが用意されており, プロキシ経由での接続もサポートされたりしているので, プロキシを介してリモートの Elasticsearch からローカルマシン上の Elasticsearch へのデータ移行もカジュアルに行えると思います.

$ elasticdump --help

さて

今回は

以下のようなステップでダンプ, インポートを行いました.

  1. VPC 上の AES にアクセス出来るホストで elasticsearch-dump Docker コンテナを利用してダンプ
  2. ダンプしたデータを SCP でローカルマシンにダウンロード
  3. ローカルマシン上に Elasticsearch を起動
  4. 起動した Elasticsearch にダンプしたデータをインポート
  5. データを確認

ダンプ (松本)

AES にアクセス出来るホスト (EC2 インスタンス) 上にて, 以下のように実行しました.

$ docker run --rm -ti -v /tmp/data:/tmp taskrabbit/elasticsearch-dump \
  --input=https://vpc-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.ap-northeast-1.es.amazonaws.com/cwl-YYYY.MM.D1 \
  --output=/tmp/cwl-YYYY.MM.D1.json \
  --type=data
$ docker run --rm -ti -v /tmp/data:/tmp taskrabbit/elasticsearch-dump \
  --input=https://vpc-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.ap-northeast-1.es.amazonaws.com/cwl-YYYY.MM.D2 \
  --output=/tmp/cwl-YYYY.MM.D2.json \
  --type=data
$ docker run --rm -ti -v /tmp/data:/tmp taskrabbit/elasticsearch-dump \
  --input=https://vpc-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.ap-northeast-1.es.amazonaws.com/cwl-YYYY.MM.D3 \
  --output=/tmp/cwl-YYYY.MM.D3.json \
  --type=data

ホスト上の /tmp/data 以下に cwl-YYYY.MM.D1.json から cwl-YYYY.MM.D3.json が生成されます.

尚, マッピングテンプレートもダンプすることが可能ですので, 必要に応じてダンプしておきましょう.

$ docker run --rm -ti -v /tmp/data:/tmp taskrabbit/elasticsearch-dump \
  --input=https://vpc-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.ap-northeast-1.es.amazonaws.com/template \
  --output=/tmp/template.json \
  --type=template

インポート

ホスト上のデータを何らかの方法 (自分は SCP を使いました) で取得し, 以下のようにデータをインポートします. インデックスへのマッピングの適用が必要な場合には, 事前にマッピングもンポートしておきましょう.

$ node_modules/.bin/elasticdump \
  --input=data/cwl-YYYY.MM.D1.json --output=http://localhost:9200/cwl-YYYY.MM.D1 --type=data
$ node_modules/.bin/elasticdump \
  --input=data/cwl-YYYY.MM.D2.json --output=http://localhost:9200/cwl-YYYY.MM.D2 --type=data
$ node_modules/.bin/elasticdump \
  --input=data/cwl-YYYY.MM.D3.json --output=http://localhost:9200/cwl-YYYY.MM.D3 --type=data

データ確認

以下のようにインデックスとして登録されていることを確認しました.

f:id:inokara:20200502073847p:plain

良い感じですね.

hits.total あたりを確認してみます.

$ curl -s -H "Content-Type: application/json" localhost:9200/cwl-YYYY.MM.D1/_search -d '
{
   "query": { "match_all": {} }
}' | jq .hits.total
4184

良い感じですね.

以上

このツールに出会うまで, 色々と試行錯誤しました. 一旦, データを CSV で書き出しておいて, インポートのスクリプトを書こうとしたり, ローカルマシンから直接 VPC 内の AES にアクセスする為にプロキシサーバーを立てようとしたり... だいぶん疲弊したところに出会った elasticsearch-dump はまさに神ツールでした.

作者の方には感謝しかありません. ありがとうございました.

2020 年 05 月 01 日 (🈲)

アクティビティ (今までの走行 (歩行) 距離)

https://pixe.la/v1/users/inokappa/graphs/fitbit-activity

Fitibit Charge2 のアクティビティから走行 (歩行) 距離を Fitbit Web API で取得して Pixela で草生やしている. 色が濃くなれば濃くなる程強度が高い (歩行, 走行距離が長い) ということで. 実装の詳細はこちら.

ジョギング

  • 引き続き, 完全休養
  • 引き続き, 安静にしておく

ギョーム

  • ウィークリーレポートを書いたり
  • ECS AMI アップデート
  • ちょっと DDoS っぽいことがあったので, 対策の検討
  • ちょっとしたアプリの修正依頼があったので修正
  • Elasticsearch に蓄積されているデータを利用した仕組みを作る為, 検証環境の準備

夕飯

  • 奥さんの十八番, おろしポン酢のハンバーグ!安定の美味しさだった