読者です 読者をやめる 読者になる 読者になる

続 select結果をcsvでファイル出力

MySQL

unionsep.hatenablog.com

先月、mysqlinto outfile でレコードをCSVファイルにサクッと取ってた記事を書きました
で、これは知ってるんだけど、今回はこれじゃダメなんだよな〜ってときに、どうしていたか思い出したので、記事書く気になりました

というのも、1. into outfile を使うと access denied になる場合も権限によってはあるね
2. mysqlsshトンネルの先にあって、その先のsshは許可されてないの・・・とか
3. ファイルにしたら巨大過ぎて、そんなの置くスペースないぜ!とか

過去を思い返すと、3. のパターンはあったな〜という思い出です
確かあれはサーバフルリプレイスしてたときに、あのvmが・・・

まぁ、というわけなんですが、手順はこんな感じ
1. mysql コマンドに -e つけてSQLを投げる
2. 1. はタブ区切りで出力されるから、 sed でタブをカンマに変換
3. csvファイルにリダイレクトする

1 . のSQLですが、文字列系はダブルクオーテーションで囲う

select
  concat('"', hoge, '"') as hoge,
  hige as hige,
  concat('"', huga, '"') as huga
from hogehoge

ワンライナーで書けるSQLだったら -e に続けて書いてもいいけど、 concat とか使ってたらそうも行かないので、SQLファイルにしておく
で、これでファイルを cat してクエリをmysqlに流し込んで、ファイルにリダイレクトしておく
この時、mysqlはタブ区切りに出力してくれるみたいなので、なんとなく拡張子を tsv にしてます

mysql -uroot hohoidb -e "`cat hogehoge.sql`" > ./hoge.tsv

2 . 3 . sed でタブをカンマに変換してリダイレクト

sed -e 's/\t/,/g' ./hoge.tsv > hoge.csv

てな感じでヌルっと出してます
まぁ、だいたいSQL用意してこんな感じでバーンとしてます

mysql -uroot hohoidb -e "`cat hogehoge.sql`" | sed -e 's/\t/,/g' > hogehoge.csv

あ、前回書き忘れたけど、csvmysqlにインポートするときはこんなSQL使ってます

LOAD DATA LOCAL INFILE '/home/ore/hogehoge.csv' INTO TABLE hogehoge FIELDS TERMINATED BY ',' ENCLOSED BY '"'

自分が完全に管理してるDBだったら、ALTER やっちゃえ!とかも思うんですが、「別チームんとこだしなー」「申請とかなー」とか思う時、エンジニアだったらあるはず!
そんなときに、サックリ自己解決したいときに使ってます
遅せークエリがボトルネックになってるんだけど、ローカルにデータ欲しいわーって思ったときとかかなぁ

今のところ、この2つの手法でデータが取れなかったことはないかなぁ


こういうのって、結構レガシーな手法で、知ってても自慢できるようなことじゃないんだけど、知らない人は知らない感じなのかなぁ
僕は結構頻繁に使うのですが、知らない人は、思いつかない限り使わないのかなぁと思ったりしてます
これらの気にいってるとこは、 select しか投げてないで!ってとこ
流石に select で壊れないっしょっていう安心感があるw
ブログ書いてるの、わりと会社の人にバレた気配がするので、役立ってくれたらうれしいなぁ〜

jQuery.DataTablesで完全一致検索

jQuery

はまった〜

知らなかったけど、とっても便利なjQueryプラグインがあって、むしろ便利過ぎて使い所迷っちゃうなって感じ
ページング実装するだけで使ってもいいじゃない
2年前ぐらいの記事が多かったから、わりと前から流行ってたみたいなんで、使い方については先人様に任せます

DataTables | Table plug-in for jQuery

で、これ、インクリメンタルサーチっぽい動きがデフォルトで、とってもかっちょいいんですが、使い所によっては完全一致させたいとかあるのかも
キーワードを入れてサブミットさせて、テーブルに並べるデータをHTML生成時に絞ってやるって方法が真っ先に頭に浮かんだんす
実装で迷ったのは、JSでスイスイ検索できるのに、完全一致させるためだけにサーバサイドに頼るってのもかっちょ悪いなと
なんか知らないけど、 DataTable() で指定するパラメタにちょちょいって書いてやれば、すぐできんじゃない?って思ってました

そんなの速攻できるっしょってたかをくくってたんですが、わりとそうでもなくて1日かかっちゃいました
まぁ、ドキュメントは英語だし、このプラグインで完全一致させたいなんて思うやつはあんまりいなかったのかなぁ
で、 jquery.dataTables.js の中身を読む旅に出発

$('#example').DataTable(
  "oSearch": {"bSmart": false}
)

Namespace: oSearch - documentation

まずこれでスマートなフィルタリングを使わないに設定

$('#example')
  .DataTable()
  .search("^" + $('#text_area').val() + "$", true, false, true)
  .draw();

つぎにこれで正規表現を使って1語検索をするのが正解みたい
結局stack overflowを参考にさせていただきました

stackoverflow.com

ここにも書いてましたけど、stack overflowのが僕にとってやさしかったです

Google Code Archive - Long-term storage for Google Code Project Hosting.

いいじゃんいいじゃんって嬉しがってたら、また一難
テキストエリアにキーワードを入れて、次に消していって、最後まで消したら、最後の検索が残ってる(´・ω・`)

if ('' != $('#text_area').val()) {
  $('#example')
    .DataTable()
    .search("^" + $('#text_area').val() + "$", true, false, true)
    .draw();
} else {
  $('#example')
    .DataTable()
    .search('')
    .draw();
}

テキスト内にキーワードが入ってないときは空で draw() したら、とりあえずは期待通りの動きをしてくれた〜
clear() とか destroy() 使ったら、デフォルトで設定したパラメタも初期化されてしまってどうしていいかわからなかったw
oSearch とか aoColumnDefs とかで設定できるのかなと思ったんだけど、ここまでにたどり着くまで半日かかってるので燃料が切れて一旦終了。。

なんでこの記事を書こうと思ったかというと、DataTablesは調べれば調べるほど高機能なプラグインだなーって思ったんですけど、便利過ぎて完全一致なんてパラメタですぐっしょって思ってしまったから
だから、多分、次同じことをしようとした時、まーた性懲りもなくすぐっしょて思いそうだったから。。
これだけスイスイ検索できることがウリ?なのに、完全一致検索は違うんじゃない?って今になって思います(´・ω・`)

ブログを書く訓練として、思いついたことを書くのを最近心がけてますが、結構ネタはあるみたい
ただ、やっぱまだ書くのに時間がかかってて、もっと精進せねばと思う感じです〜

select結果をcsvでファイル出力

MySQL

自分では結構前から便利に使ってるんだけど、意外に重宝されることが最近ありました

それがこれ

select * from hoge
into outfile '/tmp/hoge.csv'
fields terminated by ','
optionally enclosed by '"'

私の使いみちとしては、

  • 障害対応なんかで、多分このレコードがおかしいんだけど、100%自信がないときに試したい
  • 二日酔いのときに、絶対間違えられないクエリを流すとき
  • ローカルじゃない別の環境で起きてる不具合のデータをサクッととってきたいとき
  • 単にダンプが面倒なとき
  • シャーディングしてるDBで、他のDBへの参照権限がない場合、grantするの大げさやなって思ったときにファイルに出してシェルとかawkでコネコネするとき

/tmp/var/tmp 配下にcsvファイルを落として、ファイル自体の消し忘れを防止することを意識的にしてたりする

ま、mysqlの実行ユーザーにパーミッションがないところには落とせないんですけど

時と場合によっては fields terminated by の指定を変えて、タブ区切りとかスペース区切りにしてシェルとかawkperlで使いやすい形にしたりする

前のプロジェクトの方針?として、「直せるんだったらなにしてもいい」っていうなんともファンキーな空気で、まぁ立ち上げ近くからいたからかもしれませんが、、クエリ打つときは begin commit rollback してって先輩に口酸っぱく言われてました

ただ、家でたら鍵かけたかな?って思うぐらい、一時記憶装置の容量が少ない私は不安になってしまってこういう若干過度なテクニックがわりと発達したのかも

まぁ、もう大体忘れちゃいましたけど・・・

最近はMySQLばっかのプロジェクトに関わることが多いのですが、OracleとかPostgresqlとかにも同様の機能があるのかなぁ

Ansible Towerを触ってみた

Ansible

空気が暖かくなったり冷たくなったり、年々外気温に振り回される体質になってきてますね

会社は暖かいので、なにを着ていったらいいのか分からない感じですが、構成管理ってやってますでしょうか

最近、身の回りの環境が変わって、ChefとかCapistrano使ってるんだろうな〜って思われるなにかに触れる機会が多いのですが、以前はAnsibleで結構な台数のvmを管理してました

cookbookとか見たいなと思ってるのですが、これからAnsible触る機会少なそうだし、せっかく苦労して覚えたAnsibleの知識をもう少し進めたいな〜と思って、話のオチ的なノリでRedhatさんになったAnsible Towerを触りました

ところで、私が苦労していたAnsibleは、今Ansible Coreって言うそうですね
Ansible TowerとAnsible Coreって呼ぶみたいです
無料ライセンス登録したら、まさかのRedhatさんからお電話頂いて、Ansible Coreっておっしゃってて「んん?」てなったんですけど、そういうことみたいです

で、ざっと下のリファレンス読むか〜と思って目を通しました

1. Preparing for the Tower Installation — Ansible Tower Quick Install Guide v3.0.1

結構、紆余曲折したんですが、結果、こんな感じでインストールできました
vmはこんな感じ

config.vm.network "private_network", ip: "192.168.33.10"
config.vm.network "forwarded_port", guest: 443, host: 443
  • RAMは2GB以上指定なので、以下追加
config.vm.provider "virtualbox" do |vb|
    vb.memory = "2048"
end

http://releases.ansible.com/ansible-tower/setup/ansible-tower-setup-latest.tar.gz

ここからターガンジップを /usr/local/src/ に持ってきて解凍して setup.sh を実行したら依存するパッケージをインストールしてくれて、Ansible CoreがAnsible Towerをインストールしてくれました

全体的には楽々なんですけど、ポイントはこんな感じかな

  • setup.sh と同じ階層にある inventory にパスワードを事前に書いておく
    これやっておかないとAnsible Coreさんに怒られる
[all:vars]
admin_password='パスワード'
redis_password='パスワード'

pg_password='パスワード'
  • RAM2GB、disk20GBを守らないとAnsible Coreに怒られる

setup.sh 叩いたらAnsible Coreが動くのですが、満たしていない場合、怒られる
playbook書き換えたらインストールできるのですが、いきなり書き換えるのもなんだかねぇ
とはいえ、Ubuntu16.04には対応しておいてほしかったかな

  • Ansible TowerというよりCentOS7かな

実は固定IPするのに結構はまりました
/etc/sysconfig/network-scripts/ifcfg-eth1Vagrantが作ってくれてるのですが、 vagrant up 時には期待通りのIPにならず。。
networkの再起動で固定されるみたいなのですが、そもそも ifcfg-eth1 じゃないってことをこの時知りました
vagrant init ansible/tower で即できるはずですけど、それ知らなきゃねぇ・・・

www.ansible.com

で、無事にこんな感じでインストールできました

f:id:unionsep:20170130190333p:plain

うん、シンプルでいい感じ
知ってたけど、グラフが出るのいいなーって思いました
と、こうなってくると、話のオチ的な感じで構築したのに、グラフがぐにゃぐにゃなってるとこ見たくなりました
てわけで、なんか適当なplaybook作ってAnsible Towerから走らせたくなったので、次はそれしようかな〜

後でAnsibleにしたいsensu-serverのインストールログ

Ansible

sensu influxDB grafana環境を試してみたくて、とりあえずsensuとuchiwaをVagrantで実現してみた。 下記のページを写経させてもらった。
SSL証明は0.25が最新ぽかったけど、latest指定でも大丈夫そう。
実際、監視させてみて感触掴んだら、頑張ってAnsible化するっす。

qiita.com

github.com

Mackerelで遊んでみた

Mackerel

はてなさんが展開してるMackerelを使う機会に恵まれたので、ついでに監視してみたかったものを利用してMackerelを一通り触ってみました。
meetupで出会った方に仲良くしていただいたので、導入してみたよっ!ってお伝えしたら、ブログも勧められたので、書いたことないブログも書いてみました。 Markdown記法に慣れてないので、GitのWiki書くのもやっぱり苦手で、克服できたらええなぁ…

  1. Mackerelにサインアップ、agentをインストールしてみる
  2. Hubotがちょいちょい落ちてたので、独自監視項目を追加してみる
  3. 監視ルールを設定してみる
  4. Slackに投稿できるようにしてみる
  5. Slackから再起動スクリプトを叩けるようにできたらええな…
  6. まとめなど
サインアップとインストール

なんのこっちゃないです。ここ からメールアドレスで登録しました。
サインインするとオーガニゼーション、サービス、ホストを作るスタートアップガイドがあったので、その通り作りました。適当にネーミングしたの、、やっぱ失敗だったかな。

エージェントのインストールはrpmが選べるみたいだったので、その通り、叩いてみた。
特にひっかかりなく、agentもインストールできたんですが、sedでapikeyを書き換えるんですね。起動時にuser/passの入力を想像してたんで、ちょっと以外でした。

で、mackerelのページに戻ったら、もう既にcpuやらmemoryやらの6個ぐらいのグラフが出来上がってた。こいつぁ、早い!って感心しました。

Hubotを監視してみる

Slackである形式で投稿したら、メールも送信してくれるみたいなHubotのscriptを作ってたんですが、v3のHubotで運用していたせいか、3,4日ほど利用されないとSocketが切れるのか、Hubot自体もKILLされてるみたいな現象が起きてました。
休み明けに会社来て、bot無反応だったよって聞くたびに悲しくなったので、モニタリングしてみたかったのでカスタムメトリックなるものを作ってみました。

[Tue Dec 22 2015 01:31:13 GMT+0900 (JST)] ERROR Last pong is too old: 14.844
[Tue Dec 22 2015 01:31:13 GMT+0900 (JST)] INFO Reconnecting in 1000ms
[Tue Dec 22 2015 01:31:14 GMT+0900 (JST)] INFO Attempting reconnect
[Tue Dec 22 2015 01:31:14 GMT+0900 (JST)] INFO Connecting...
[Tue Dec 22 2015 01:31:43 GMT+0900 (JST)] INFO Slack client closed, waiting for reconnect
[Tue Dec 22 2015 01:32:18 GMT+0900 (JST)] ERROR undefined
[Tue Dec 22 2015 01:32:18 GMT+0900 (JST)] INFO Reconnecting in 2000ms
[Tue Dec 22 2015 01:32:20 GMT+0900 (JST)] INFO Attempting reconnect
[Tue Dec 22 2015 01:32:20 GMT+0900 (JST)] INFO Connecting...
[Tue Dec 22 2015 01:32:21 GMT+0900 (JST)] INFO Logged in as <むふふ>, but not yet connected
[Tue Dec 22 2015 01:32:22 GMT+0900 (JST)] INFO Slack client now connected
error: Forever detected script was killed by signal: SIGKILL

落ちてた時のログがこれ。
どうもKILLシグナルが出てるみたいだから、プロセス監視できたら良いかなーって思ってたら、こちらの方と全く同じ要件でした。。確かに私もよくわからなかったです。(´・ω・`)

arata.hatenadiary.com

で、いろいろ調べてると、公式プラグイン集なるものがGitHubに集められていて、またまたrpmでインストールできる事が分かりました。で早速入れてみました。

mackerelio/mackerel-agent-plugins

  • mackerel-plugin-apache2
  • mackerel-plugin-php-apc
  • mackerel-plugin-memcached

また特になんのひっかかりもなくインストールできて、/usr/local/binに監視スクリプトが配置されていました。ヘルプにある通り、/etc/mackerel-agent/mackerel-agent.confコメントアウトを解除してあげたら即反映されてました。
Apacheだったらserver-statusを見れるようにしとくとか、段取りがあるプラグインもありますが、とってもお手軽でした。Sensuは触ったことないけど、munin触ったことあったらつまづく箇所ないんじゃないかっていうぐらいでした。

ということで、どうやら/usr/local/binにmackerel-pluginから始まるスクリプトを用意して食わせるって感じだったので、シェルスクリプトだけど作ってみました。

at /usr/local/bin/mackerel-plugin-hubot

#!/bin/sh
echo -e "<むふふ>-hubot\t`ps aux|grep hubot|grep adapter|wc -l`\t`date -u +%s`"

at /etc/mackerel-agent/mackerel-agent.conf

[plugin.metrics.<むふふ>-hubot]
command = "/usr/local/bin/mackerel-plugin-hubot"

文字列 Tab 数字 Tab date -u +%sな感じで標準出力したら、うまいこと読んでくれました。こんなんでも食ってくれるんだったら、perlでもphpでもなんでも作れそうです。公式プラグイン集はGo言語が多かったようです。agentがGo言語製だからかな?

監視ルールを設定してみる

Monitorsの監視ルールを追加から、作ったメトリックのルールを追加してみました。監視対象のメトリックから、絞り込んで設定。プロセスが1未満だったらWarningにもCriticalにもする的な設定にしてみました。
どうでもええけど、不等号がどっちやったっけ?ってちょっとだけ迷いました。

Slackに投稿

Monitorsのチャンネル設定から設定しました。アラートはEmailもSlackもチャンネルって呼ぶそうです。
SlackはIncoming WebhooksのURLを設定すればいいみたいですね。
で、おもむろにHubotをstopしてみたら、グラフ付きでちゃんと通知来ました!メールボムみたいにギャンギャン通知くるのかなー?どうなのかなー?って10分ほどおいてみましたけど、そうでもなかったです。これは嬉しいですね。
待ってるの飽きてきたので、startしたら、グラフ付きでちゃんとokきました。

SlackからHubotを再起動

Slash CommandsからJenkinsAPIを叩いて行けそうだったんですが、認証通すのがしんどかったので、それ用のWebAPIを用意した方が速そうって気付きました。
でも、もはやMackerel関係ないし、時間切れだしで、また今度作ろうと心に誓って作業終了にしました。

まとめ

一通りmackerelを触ってみた感想は、既存のツールを意識した作りにしてるのかなーって思いました。今使ってるツールのこうならんかなー的な欲求を汲んでくれてるかなと。
Zabbixのグラフ探すのが未だに苦手、muninの通知設定苦手〜とか。。あれ、俺だけか・・・

ブログは、、あれですね。書くのに超時間かかりました。。世のブロガーさんはすげーなって感心です。もっと画像とか入れたら華があったんだろうなぁ〜。