2015年4月20日月曜日

Nagiosでデータ転送量を監視する

Andrew Hart Follow All Systems GO! https://www.flickr.com/photos/andrewfhart/8106200690
SNMPエージェントである Net-SNMP をインストールして使えるようにします。
SNMPを使用して、データ転送量をNagiosで監視します。
Net-SNMPの使い方は、若干複雑なのですが、最低限の設定で利用できるように解説しました。
環境は、Amazon Linux AMI 2015.03 (HVM) - ami-cbf90ecbです。


Net-SNMPを準備

net-snmpをインストール
# yum -y install net-snmp net-snmp-utils
# chkconfig snmpd on
snmpdの設定ファイルを編集
# emacs /etc/snmp/snmpd.conf

# Make at least  snmpwalk -v 1 localhost -c public system fast again.
#       name           incl/excl     subtree         mask(optional)
#view    systemview    included   .1.3.6.1.2.1.1
#view    systemview    included   .1.3.6.1.2.1.25.1.1
view    all     included        .1      80

####
# Finally, grant the group read-only access to the systemview view.

#       group          context sec.model sec.level prefix read   write  notif
#access  notConfigGroup ""      any       noauth    exact  systemview none none
access  notConfigGroup ""      any       noauth    exact  all none none
snmpdをリスタート
# service snmpd restart
インタフェース名一覧を表示
# snmpwalk -v 1 -c public localhost ifDescr
IF-MIB::ifDescr.1 = STRING: lo
IF-MIB::ifDescr.2 = STRING: eth0
eth0のインデックス番号は「2」であることが分かります。eth0に関して調べるときには、この番号を使います。
送受信オクテット累積数を確認してみます。
IF-MIB::ifInOctets.1がlo、IF-MIB::ifInOctets.2がeth0です。
bpsとして見るには、取得した値の差 × 8 ÷ 取得間隔(秒)というように計算します。

受信オクテット累積数
# snmpwalk -v 1 -c public localhost ifInOctets
IF-MIB::ifInOctets.1 = Counter32: 3755493095
IF-MIB::ifInOctets.2 = Counter32: 541310019
送信オクテット累積数
# snmpwalk -v 1 -c public localhost ifOutOctets
IF-MIB::ifOutOctets.1 = Counter32: 3757407963
IF-MIB::ifOutOctets.2 = Counter32: 361982746
Net-SNMPの準備が出来ました。


check_snmpを実行

check_snmpプラグインを使ってみます。
nagios-nrpeとcheck_snmpプラグインがない場合は、インストールしておきます。
# yum -y install nagios-nrpe
# yum -y install nagios-plugins-all
check_snmpプラグインにパラメータを設定して実行。 OIDを2つ設定します。IF-MIB::ifHCInOctets.2とIF-MIB::ifHCOutOctets.2です。それにあわせて、-uのUnits labelを2つ設定しています。 警告50MBps、クリティカル100MBpsです。
# /usr/lib64/nagios/plugins/check_snmp community -H 127.0.0.1 -C public -P 2c -o IF-MIB::ifHCInOctets.2 -o IF-MIB::ifHCOutOctets.2  -w 52428800 -c 104857600 --rate --rate-multiplier 8 -u "bps in." -u "bps out." 
初回実行時には情報の記録のため以下の出力になります。
No previous data to calculate rate - assume okay
2回目移行から以下のように情報が表示されます。
SNMP RATE OK - 74733.6 bps in. 155997.6 bps out. | IF-MIB::ifHCInOctets.2=74733.6 IF-MIB::ifHCOutOctets.2=155997.6
check_snmpプラグインの動作に問題がなかったら、nagios(nrpe)のために一時ファイルのパーミッションを設定しておきましょう。
# chown nrpe:nrpe /var/check_snmp
あとは、Nagiosに組み込んでおけばOKです。


参考資料
Monitoring Routers and Switches
http://nagios.sourceforge.net/docs/3_0/monitoring-routers.html
snmpd 設定方法
http://changineer.info/server/monitoring/monitoring_snmpd.html
net-snmpの設定 - Qiita
http://qiita.com/toshiro3/items/e8f87da88cd383a6421d
CentOSでNet-SNMPインストールと設定 | GOISBLOG
https://genchan.net/server/4393
Nagiosでサーバのトラフィック監視を行う方法 – Jラボ « Jラボ
http://junrei.dip.jp/wordpress/nagios/nagios%E3%81%A7%E3%82%B5%E3%83%BC%E3%83%90%E3%81%AE%E3%83%88%E3%83%A9%E3%83%95%E3%82%A3%E3%83%83%E3%82%AF%E7%9B%A3%E8%A6%96%E3%82%92%E8%A1%8C%E3%81%86%E6%96%B9%E6%B3%95/
Nagiosでトラフィックグラフを作成/監視 check_snmp | ITオフィスサポートとシステム開発|システムガーディアン 東京都中央区八丁堀
http://sys-guard.com/nagios%E3%81%A7%E3%83%88%E3%83%A9%E3%83%95%E3%82%A3%E3%83%83%E3%82%AF%E3%82%B0%E3%83%A9%E3%83%95%E3%82%92%E4%BD%9C%E6%88%90%E7%9B%A3%E8%A6%96-check_snmp/
Nagiosのcheck_snmpプラグインの --rate オプションを試す - blog.nomadscafe.jp
http://blog.nomadscafe.jp/2013/02/nagioscheck-snmp---rate.html

2015年4月16日木曜日

GitHubのパンチカード

GitHubにはパンチカードという機能があって、いつ仕事したのかを可視化できて面白い。
レポジトリの右側のリンクから確認できます。
パンチカードのグラフは、曜日と時間にもとづいてあなたのリポジトリの更新頻度を示しています。
黒丸の大きさはコミットの頻度を示しています。
このグラフにはマージコミットは含まれていません。
上記のような仕様だそうです。
自分がメインで使っているレポジトリのパンチカードを見たら、おもっていたより ”メリハリをつけて仕事をしている” と言ってもいいような絵になっていました。
そこはかとなく。緊急対応もしているように見えますね。

参考資料
About Repository Graphs - User Documentation
https://help.github.com/articles/about-repository-graphs/

2015年4月15日水曜日

Embulkを使ってJSONデータをGoogle BigQueryに投入する

erokism Follow Bulk? paste up in Manchester https://www.flickr.com/photos/10295270@N05/4163403080
Embulkのアウトプット・プラグインであるembulk-output-bigqueryを使って、JSONデータをGoogle BigQueryに投入します。

JSONのサンプルデータを用意。
# emacs /tmp/json_sample.json
{ "first_name":"John", "last_name":"Lennon", "age":20 }
{ "first_name":"Paul", "last_name":"Maccartney", "age":22 }
Google BigQueryのスキーマファイルを用意。
# emacs /tmp/schema.json
[
  {"name":"first_name","mode":"REQUIRED","type":"STRING"},
  {"name":"last_name","mode":"REQUIRED","type":"STRING"},
  {"name":"age","mode":"REQUIRED","type":"INTEGER"}
]
Javaをインストール。
# yum install -y java-1.8.0-openjdk
Embulkをインストール。
# curl --create-dirs -o ~/.embulk/bin/embulk -L "http://dl.embulk.org/embulk-latest.jar"
# chmod +x ~/.embulk/bin/embulk
# echo 'export PATH="$HOME/.embulk/bin:$PATH"' >> ~/.bashrc
# source ~/.bashrc
# embulk --version
embulk 0.6.2
Embulkプラグインをインストール。
# embulk gem install embulk-parser-jsonl
# embulk gem install embulk-output-bigquery
# embulk gem install embulk-formatter-jsonl
Embulkの設定ファイルを用意。
service_account_email、project、path_prefix、datasetにGoogle BigQueryのアカウント情報を記述します。
テーブルは自動生成オプションを有効にして、テーブルの末尾に _%Y%m%d を付けるようにしています。
# emacs config.yml
exec: {}
in:
  type: file
  path_prefix: /tmp/json_
  parser:
    type: jsonl
    root: $.students
    schema:
      - {name: first_name, type: string}
      - {name: last_name, type: string}
      - {name: age, type: long}
out:
  type: bigquery
  service_account_email: your_id@developer.gserviceaccount.com
  project: your-project-000
  p12_keyfile_path: /path/to/p12_keyfile.p12
  dataset: my_dataset
  path_prefix: /var/tmp/sample
  source_format: NEWLINE_DELIMITED_JSON
  file_ext: .json.gz
  delete_from_local_when_job_end: 1
  auto_create_table: 1
  schema_path: /tmp/schema.json
  table: students_%Y%m%d
  formatter:
    type: jsonl
  encoders:
    - {type: gzip}
Embulkインプットのプレヴューを実行。
# embulk preview config.yml
2015-04-15 15:29:36.316 +0900: Embulk v0.6.2
2015-04-15 15:29:37.649 +0900 [INFO] (preview): Listing local files at directory '/tmp' filtering filename by prefix 'json_'
2015-04-15 15:29:37.654 +0900 [INFO] (preview): Loading files [/tmp/json_sample.json]
+-------------------+------------------+----------+
| first_name:string | last_name:string | age:long |
+-------------------+------------------+----------+
|              John |           Lennon |       20 |
|              Paul |       Maccartney |       22 |
+-------------------+------------------+----------+
Embulkを実行。
# embulk run config.yml
2015-04-15 06:35:03.544 +0000: Embulk v0.6.2
2015-04-15 06:35:05.422 +0000 [INFO] (transaction): Listing local files at directory '/tmp' filtering filename by prefix 'json_'
2015-04-15 06:35:05.426 +0000 [INFO] (transaction): Loading files [/tmp/json_sample.json]
2015-04-15 06:35:06.752 +0000 [INFO] (transaction): {done:  0 / 1, running: 0}
2015-04-15 06:35:07.027 +0000 [INFO] (task-0000): Writing file [/var/tmp/sample.000.00.json.gz]
2015-04-15 06:35:07.044 +0000 [INFO] (task-0000): Job preparing... project:your-project-000 dataset:my_dataset table:students_20150415
2015-04-15 06:35:07.049 +0000 [INFO] (task-0000): table:[students_20150415] will be create if not exists
2015-04-15 06:35:07.054 +0000 [INFO] (task-0000): Upload start [/var/tmp/sample.000.00.json.gz]
2015-04-15 06:35:11.120 +0000 [INFO] (task-0000): Upload completed [/var/tmp/sample.000.00.json.gz]
2015-04-15 06:35:11.125 +0000 [INFO] (task-0000): Job executed. job id:[job_kRqcNXo8EXrCneT9h3cCUpR67lQ] file:[/var/tmp/sample.000.00.json.gz]
2015-04-15 06:35:11.487 +0000 [INFO] (task-0000): Checking job status... job id:[job_kRqcNXo8EXrCneT9h3cCUpR67lQ] elapsed_time:362ms status:[PENDING]
2015-04-15 06:35:21.766 +0000 [INFO] (task-0000): Checking job status... job id:[job_kRqcNXo8EXrCneT9h3cCUpR67lQ] elapsed_time:10641ms status:[PENDING]
2015-04-15 06:35:32.112 +0000 [INFO] (task-0000): Checking job status... job id:[job_kRqcNXo8EXrCneT9h3cCUpR67lQ] elapsed_time:20987ms status:[RUNNING]
2015-04-15 06:35:42.351 +0000 [INFO] (task-0000): Job statistics [{"inputFileBytes":"83","inputFiles":"1","outputBytes":"48","outputRows":"2"}]
2015-04-15 06:35:42.352 +0000 [INFO] (task-0000): Job completed successfully. job id:[job_kRqcNXo8EXrCneT9h3cCUpR67lQ] elapsed_time:31227ms status:[SUCCESS]
2015-04-15 06:35:42.352 +0000 [INFO] (task-0000): Delete local file [/var/tmp/sample.000.00.json.gz]
2015-04-15 06:35:42.352 +0000 [INFO] (transaction): {done:  1 / 1, running: 0}
2015-04-15 06:35:42.367 +0000 [INFO] (main): Committed.
2015-04-15 06:35:42.367 +0000 [INFO] (main): Next config diff: {"in":{"last_path":"/tmp/json_sample.json"},"out":{}}
Embulkの処理が完了しました。
確認してみましょう。


JSONデータがGoogle BigQueryに投入されました。

続いて大量データを投入してみます。
環境は、EC2のc4.large(Amazon Linux AMI 2015.03 (HVM), SSD Volume Type)です。
1億行のJSONを用意しました。ファイルサイズは5.7GBです。
実行結果は以下のようになりました。
2015-04-15 07:33:04.426 +0000: Embulk v0.6.2
2015-04-15 07:33:06.352 +0000 [INFO] (transaction): Listing local files at directory '/tmp' filtering filename by prefix 'json_'
2015-04-15 07:33:06.357 +0000 [INFO] (transaction): Loading files [/tmp/json_sample.json]
2015-04-15 07:33:07.632 +0000 [INFO] (transaction): {done:  0 / 1, running: 0}
2015-04-15 07:33:08.036 +0000 [INFO] (task-0000): Writing file [/var/tmp/sample.000.00.json.gz]
2015-04-15 07:57:19.158 +0000 [INFO] (task-0000): Job preparing... project:your-project-000 dataset:my_dataset table:students_20150415
2015-04-15 07:57:19.164 +0000 [INFO] (task-0000): table:[students_20150415] will be create if not exists
2015-04-15 07:57:19.171 +0000 [INFO] (task-0000): Upload start [/var/tmp/sample.000.00.json.gz]
2015-04-15 08:00:38.361 +0000 [INFO] (task-0000): Upload completed [/var/tmp/sample.000.00.json.gz]
2015-04-15 08:00:38.366 +0000 [INFO] (task-0000): Job executed. job id:[job_LoZky6tlYHA0hKEnT279_Ytni5c] file:[/var/tmp/sample.000.00.json.gz]
2015-04-15 08:00:38.620 +0000 [INFO] (task-0000): Checking job status... job id:[job_LoZky6tlYHA0hKEnT279_Ytni5c] elapsed_time:254ms status:[PENDING]
中略
2015-04-15 08:07:07.867 +0000 [INFO] (task-0000): Job completed successfully. job id:[job_LoZky6tlYHA0hKEnT279_Ytni5c] elapsed_time:389501ms status:[SUCCESS]
2015-04-15 08:07:07.867 +0000 [INFO] (task-0000): Delete local file [/var/tmp/sample.000.00.json.gz]
2015-04-15 08:07:07.894 +0000 [INFO] (transaction): {done:  1 / 1, running: 0}
2015-04-15 08:07:07.911 +0000 [INFO] (main): Committed.
2015-04-15 08:07:07.911 +0000 [INFO] (main): Next config diff: {"in":{"last_path":"/tmp/json_sample.json"},"out":{}}

real 34m7.619s
user 24m33.712s
sys 0m38.524s
バッファ用のファイル作成に時間がかかっています。開始から完了まで34分でした。

まとめ
Embulkを使ってJSONデータをGoogle BigQueryに投入するまでの流れを追ってみました。
コマンドひとつでデータを投入できるのが良いです。
Google BigQueryはストリームでのインポートも可能ですが、ストリーム処理にかかる料金が必要だったり、APIが不安定で、データの投入失敗・重複などデメリットがあります。より正確なデータの投入を目指すのならば、Embulkは選択肢のひとつになると思います。
https://cloud.google.com/bigquery/quota-policy
実際に運用するときには、Quota Policyの制限に注意しましょう。