俺の報告

RoomClipを運営するエンジニアの日報(多分)です。

slackにメッセージをpostするシェル - 日報 #138

何でもかんでもslackにぶち込みやがって!
でもそれでいい〜んです。

今日はそんな話。

Notification系の情報はもうSlackに集約していいと思います。
なんせ便利だし。
ということなので、まずbashでslackポストが出来るようなシェルを手元にもっておきます。
すごい気が楽になりますよね。

ということでまず、slackでpostするシェルスクリプトを。

理想はこんな感じで呼び出せるように。

echo "Body Message" | ./slack_post.sh -c Hoge_channel -u Post_user -m "Header message"

要はシェルの結果をパイプで貰うshスクリプトがあって、
-c でチャンネル名、 -u でポストユーザ名、 -m でヘッダーメッセージ、
シェルの結果がポストの内容、
こんな感じで使えたら超便利ですね。

結果こんな感じに。

#! /bin/bash

set -eu
CHANNEL="def_channel" # DONOT USE '#'
USERNAME="slack_post_shell"
MESSAGE="TEST"
HOOKS_URL="https://hooks.slack.com/services/XXXXX"

for OPT in $*
do
    case $OPT in
        '-c' )
            CHANNEL=$2
            shift 2
            ;; 
        '-u' )
            USERNAME=$2
            shift 2
            ;; 
        '-h' )
            HOOKS_URL=$2
            shift 2
            ;; 
        '-m' )
            MESSAGE=$2
            shift 2
            ;; 
    esac
done

# slackのために無理やり\nを出力させる
MESSAGEFILE=/tmp/webhooks
rm ${MESSAGEFILE}
if [ -p /dev/stdin ] ; then
    cat - | tr '\n' '\\' | sed 's/\\/\\n/g'  > ${MESSAGEFILE}
fi

POST_MSG="${MESSAGE}\n"`cat ${MESSAGEFILE}`'\n'

curl -X POST --data-urlencode "payload={\"channel\": \"#${CHANNEL}\", \"username\": \"${USERNAME}\", \"text\": \"${POST_MSG}\"}" ${HOOKS_URL} 1>/dev/null 2>&1

うーん、tmpのところが若干不安だから$mktmpみたいなの使うといいかもしれないが、よく知らないので放置。
基本的にはcat - で受け取ったものをtmpファイルに保存して、という無駄経由をしているのは、sedコマンドが
unterminated substitute in regular expression
を吐き出しちゃうからです。
このへんとか参照 この方が楽なんすよね。
改行をなんとかうまく変換する方法ってないんすかね。。。

さて、これでおくれるようになりました。
あとはデプロイツールの最後に吐くなりなんなり、自由にしたらんかい!
という感じです。
便利ですね。

今更聞けない、べき則、ロングテール、ジップ則について - 日報 #137

日々是勉強でございます。
RoomClipに対するアカデミックな側面からのアプローチも、
少しずつ形になりつつあります。
ということで今日はそんな話。

これ以降このブログでも乱発されるワードがあるので、
まずそいつについて少し。

べき則とかいうワードがあります。
本当はべき乗則とか言って、もっと本当は累乗とか言うらしいんだけど、まぁそのへんの話です。

やれロングテールだ、
やれパレートだとかいう言葉はとても便利ですが、
改めて厳密に、と言われると大概難しくなるのがこの界隈のよくないところです。
ロングテールをぼんやりと「超売れてるのは一部だけ、ほとんどあんまり売れてない、けど売れてない奴すごい量」みたいなイメージで、 そのままべき則だのジップ則だのを理解しておけばいいだけの話だとも思うので、
それを目指します。

べき則というのはそもそも、累乗の話です。
xの4乗、とかいったらもうそれべき則の話です。
これを本質的に言うならば、4乗とか5乗とかはどうでもよくて、
とにかく「自分と同じものをかける操作」というものを「べき乗する」と呼ぶんですね。
だから、べき乗関数といったら、もうすごい簡単で、

f(x) = x^k

これで終わりです。
Wikipediaにいったらランダウの記号Oとか比例定数aとかが記載されてますが、
早い話が「この関数を超支配している部分」は x^k だけです。
細かいことはいいので、こいつだけみてりゃいいんです、という式ですね。
どうしてもランダウが気になる方は、この式を見ればなんとなくランダウが「どの程度適当なやつか」がわかると思います。

(x + 1)^2 = x^2 + 2x +1 => x^2 + O(x)

2x + 1 とかゴミなんでまとめときますね、ランダウで。
大事なのはx^2なんで、それ以外はほぼ大勢に影響及ぼさないんで、
くらいのノリで理解してOKです。

話が脱線した。

とにかく「自分と同じものをかける操作」というものを「べき乗する」と呼ぶんですね。

さて、
べき乗とやらがたんに「自分をかける操作」ということがわかった上で、
なぜこの関数がこうももてはやされるのかという話に移ります。
有名なジップ則の話です。

いろんな説明の方法があると思いますが、
すげーーーーー簡単に、でも概ね間違わないように説明してみます。

じゃぁ皆しってるロングテール的な状況を想定してみます。
さらに分かりやすいようにアイスクリーム売り場を想定してみます。

あるアイスクリーム屋の味毎の売上をみてみると、「バニラ味一強」状態でした。
続いてチョコ味、ストロベリー味、と中々の強豪が続きますが、
まぁ大体4位くらいから雑魚化していき、
店長の気まぐれで作ったシリーズ100種(春の七草味、タバコ味などのゴミ)に至っては1件売れればいい程度のクソっぷりだったとします。
でも10位から100位までの売上を足し上げると、まぁそこそこあるなぁくらいだったとします。

ようはロングテールだったわけですね。

さて、この時バイトの平山君はこう思ったんです。
「順位の値が小さいやつだと、売上数は大きい。順位の値が大きいと、売上数は小さい。」
当たり前です。
「じゃぁ、なんとなーく、(順位の値)と(売上数)を掛けあわせたら、大体全部同じくらいの値になるんじゃないの?」
小さい奴は大きくて、
大きい奴は小さい、
と聞いたらなんとなく「かけたら一緒くらいじゃね?」とか思うのは人の性です。
つまり、順位の値rと売上数nをかけたらaになる!という予想をしたんですね。
これって要は、

順位の値:r, 売上の値:n, なんか適当な定数:a としたら、
r * n = a
n = a / r

っていうことです。
ですが、勿論そんな簡単じゃないんですね。
全然そんな風にならない。
でもバイトの平山君は粘着質だったので、
「でもさ、順位が小さくなれば売上が大きくなるわけでしょ、なんか関係があるわけでしょ。」
ってことで、横軸に順位、縦軸に売上をとってプロットしてみるんですよ。

するとこれはもう皆知っての通り、
ロングテール」のグラフの形になるわけです。
もうさっき触れてるから当たり前です。

「あぁーロングテールってやつかぁ。。。すごいy=1/xの形には似てるけどなぁ。。。」

確かに最初の予想である、 n = a / r の形には凄い似ています。
でもそうじゃない。
困ったところに神の声です。

「これこれ、そこの能なし。いいから黙って対数をとってみるのじゃ。。。

信託を受けて、横軸にlog(順位)、縦軸にlog(売上)をとってみることにすると。

な、なんと、
見事に直線になるではないか!
ってことは式が簡単に導ける!
中学でやった比例のグラフや!簡単や!
確かy=ax+b的な話のはず!

y: log(売上), x: log(順位) としたら、
log(売上) = k * log(順位) + b
log(n) = k * log(r) + b

bは適当だから、b = log(B)とかおいてもええやんな。

log(n) = k * log(r) + log(B)
log(n) = log( r^k * B)
n = r^k * B
ごちゃごちゃしたが、最終形は、
r^(-k) * n = B

おぉ!なんか当初目指していた形、

r * n = a

これにめっちゃ近い!
ただ r が r^(-k) とかいうワケワカランものになってる!
これどういうことかわからないけど、
冒頭の「べき乗」の議論に戻ると、たしかべき乗は「自分自身をかける操作」をいうのであって、
^(-k)とかどうでもいいんだったよね。
じゃぁこれは「rのべき乗」ってことだよね。

つまりこれは、「rのべき乗とnの積は一定!」っていうことだ!
最初の予想「順位と売上の積は一定」は間違っていたけど、
「順位のべき乗と売上の積は一定」というのが正解だったんだね!

神「そうじゃったのだよ、、、この能なし、、、」

ってことになります。
んで恐らく、これがジップ則です。
具体的に言うと、

1位 バニラ味:売上 1,000個

4位 バナナ味:売上 ?個

となっていたら、単純に「順位と売上の積は一定」なら、バナナ味は250個なんだけど、
これは間違っていて、
「順位のべき乗と売上の積は一定」なのだから、 もしべき乗の指数kが2とかなら、62個までさがっちゃうんです。
逆に指数kの値が1/2なら、まだ500個なんですね。

さて、
長ったらしくジップ則を説明してきましたが、
そもそもなぜこんなにべき則が面白がられるかというと、
スケール不変という性質があるからなんですね。

今までの議論でわかったこととしては、
大事なのは a とか B の値じゃなくて、
「べき乗の指数はいくつなの?」ということに尽きるということです。
売上の話で言うと、指数kが猛烈に重要な値で、
グラフの形を決めているのはこの変数です。
よってこれを一般にスケーリング指数とかと呼ぶわけですね。
え、じゃぁBとかその、一定の値は?
これは本当に全く重要じゃないんです。
例えば、スケーリング指数が2で同じなら、1位のバニラの売上が1,000であろうと1億であろうと、
バナナ味までの落ち込み方は一緒で、
要は1位が1000の時のグラフを書いて、
その縦軸の値の1000のところを1億に書き直せば、
そのまま1億の時のパターンになっちゃうわけです。

これはフラクタルなどによく見られる性質で、
すごい面白い性質ですよね。
だからというわけではないですが、
この「べき則」というものはやけに面白がられます。

あぁHeaps則も勉強しようと思ったが、もう書くのが面倒なので、今日はここまで。

GoogleAppScriptで添付ファイルをS3へアップロード - 日報 #136

何でもかんでも自動化というのが世界の要望みたいです。
まぁいんでないすかね、自動化。
概ね賛成です。

僕は自動化に対して意識が低かったのですが、
この姿勢はそろそろ修正しないと駄目ですね。
言い訳は「面倒」と「怖い」です。
「何が起こるか怖いから、ちゃんと見ながらやりたい」
「手動でやるなら、ある程度適当でいい。自動化のために気を遣うシステムにするのは面倒」
この2つの発想の本当の根本的な原因は性格とか忙しさとか、そういうことじゃなくて、
単純に「技術力不足」ということだと思います。

なので、そろそろこの姿勢は正さないといけません。
隣に座る鉄人N氏の力強い実装力に学ぶことは多いです。

ということで、手始めに数値取得のあたりで気になっていたものがあったので、
さっそく自動化しましたが、結果的にこれはよい練習になりました。
なのでここで報告します。

シェルスクリプトのバッチや、
プロセスループならまぁまだ馴染みがありますが、
重要なのは「馴染みのない言語や開発環境でもしっかり自動化まで見越したプログラム」を書いてみる。
ということでしたので、
おあつらえ向きな開発環境、
Google Apps Scriptをいじってみました。

GoogleAnalyticsやAWSのようなごついサービスは必ずと言っていいほどAPIが開放されており、
どこからでもつつける設計になっていますが、
もちろんすべてのサービスがそういうわけではないのです。
例えばADEBisなどは定期レポートシステムこそ存在していますが、CSVファイルを添付して毎日メールしてくるだけです。
これをどうやって自動化システムに組み込むのか、中々悩ましいものでした。

ですが、Gmailに情報がバトンタッチされた時点で世界は開かれるわけです。
IFTTTとかを利用するという発想もありますが、
もっと原理的にこの「Gmailから世界へ!」感を感じてみようと思います。

ということで、
Gmailで受信した特定のメッセージに添付されたファイルを、
S3にアップロードする、
というGoogle Scriptを実装してみました。

まずはGoogle ScriptでS3にファイルを送信できるのか。
http://engetc.com/projects/amazon-s3-api-binding-for-google-apps-script/
ここにありました。
では続いて、Gmailを特定の条件で検索して、その添付ファイルをオブジェクトとして取得できるか?
多少仕様は違いますが、
http://noriaki.hatenablog.com/entry/gmail-attachments-in-google-drive-based-on-google-apps-script
ここにあります。

これで出揃いましたので、即コーディングしてみましょう。

結果、こんな感じに。
流れ的にはこんな感じ。

6時間に1回下記の処理をGmailに対して行う。

  1. gmailを特定のキーワードで検索
  2. 検索結果の全てのメッセージにおいて添付されているファイルを取得
  3. 取得したファイルを特定のS3にアップロード

こうしておけばあとは完全に自由に自分のAWS領域から料理できます。
Gmailは世界への扉でした。   あぁ疲れたから今日はここまで。

wordpressのwp_optionを直いじり - 日報 #135

なんかえれぇ疲れてるけど少しずつ進展がある日々で中々刺激的です。
フットサルやったらもんすげー足いたい。

それで。

wordpressをいじる作業が一旦終わり、
SEO的な調整最適化に入る前に、
ちょっと色々とチップスが発生したので共有を。

wordpressを無理やりハックしようとすると、
当然DBに対してもメスが入ります。
管理画面からいじるのがワケワカラン状態になってしまったら、
直接DBいじったるわいと思うのも無理からぬことです。
本当は駄目ですが。
それでも文字列置換くらいだったら、、、と軽い気持ちでやっちゃうと思わぬ落とし穴にはまります。
wp_optionなどはシリアライズされた配列データなどがそのままぶっこんであったりするので、
単純に文字列置換などを行うだけではエラーになってしまいます。

なのでシリアライズされたoption_valueをスクリプトでなんとかせんといけません。
何度も言いますが、面倒臭がらず、腐らず、折れず、変更管理画面を探しだして変更したほうが色々安全です。
ですが、「あぁ駄目だ!もうこれはDB倒すしか無い!」ってなったら下記手順でやるといいです。

凄い単純で、
一旦シリアライズ文字列をunserializeして、配列にします。
ここで再帰的に配列を全参照して文字列置換を行うという手法もありますが、
かったるいのでjson_encodeして文字列にします。
そこでpreg_replaceで文字列置換。
そしてjson_decodeして配列に戻し、serialize。
以上です。

<?php echo serialize(json_decode(preg_replace("/".preg_quote(@$argv[2])."/",@$argv[3],json_encode(unserialize(file_get_contents(@$argv[1])))),TRUE)); ?>

無駄にワンライナーです。
引数にシリアライズされた文字列が記載されたファイル名、
置換対象文字列、
置換後文字列、
の3つをあげればシリアライズされた文字列を返します。
わっかりづら!

じゃぁね。

PlanDoCheck IT NOW!! - 日報 #134

どの辺が日報なんだよ。 週報になってんじゃねぇかよ。
まったく、何してたんだよ仕事だけどよ。

なんかむちゃくちゃやることあるけど、
楽しい毎日です。
言うは易し行うは難し、略してPDCAですが、
自分の食う飯すらPDCAできない奴が、
属人的力でもって組織的にPDCAを目指すとか土台無理なわけです。
だから出来るだけ外部化した機能のみでもってPDCAが回るようにせしめることが必要なわけです。
っていうかPDCAとかどうでもよくて、
物事は当たり前のように「調査・計画」してから「目的」をもって「実行」されて、
その「達成率・進捗」は具に監視され、「結果の評価」は然るべきタイミングで整理されるべきなんですよ。
そうじゃなければ「俺無双」みたいに、とりあえずガンガン突き進むのを断行すればいいはずなんですよ。

あぁワケワカランが、
とにかくガツガツ必要な物を作りまっせ。
またそれについて詳しく報告するで。
そいじゃ。

寝る前にただ書いた文章 - 日報 #133

Wordpressというジャングルに迷いこんだ結果、
「もうワケワカランからここに村を作って自活します」的なコードを書くという結論に至りました。
数多あるプラグインコードは足の裏よりどうでもいいと切り捨てて、
とにかく途中でバイパスした自作スクリプトに全てを注ぎ込む毎日です。
functionのたらい回しに腹を立てる毎日です。

さて、
ここ2,3日はGA APIとDB連携及び、d3.jsを使った可視化に余暇の全てを放り込んでいます。
データ可視化といえば僕の学部時代のメインテーマですが、
今になってもっと真面目に取り組んでいればなぁと嘆く日々です。

あれ、
書くことが無いから質問を落としていきます。
DB連携でPHPとかのスクリプトとd3.jsとかでブラウザ描画するのと、
Rstudioみたいなクライアントソフト使ってゴリゴリ計算してグラフ描画するのと、
どっちのほうが気持ちがいいかなぁとボンヤリ思っています。
あとDropBoxのkey-valueのDB-APIとかを使ったいい例とか知っている人がいたら、
是非とも教えて欲しいです。
便利そうなのに、何に使ったらいいか全くわからないので、、、

ワークフローから数値管理、そして数値計画へ - 日報 #132

なんかすげぇやることいっぱいだよ!
当たり前だけど!

最近シコシコと夜に1人作業をしております。
メインの開発ラインと数値管理や経営課題に8割をあてて、
残り2割程度でちょっと思いついたことをやっております。

何かというと。

今年の初めからちょいちょい悩み事をここで書いておりますが、
僕の中では大きく分けて3つありました。

1つ目は、複数人数でのワークフローです。
具体的には、複数のプロジェクトで、それぞれ複数人が、同じリポジトリに変更を加える、
という一連の流れを、プロジェクト毎のスケジュール立案から、安全な本番反映までしっかり整えることです。
今のところgitとredmine、そしてエクセルによる開発ライン管理で何とかなっておりますが、
勿論ジェンキンスおじさんの導入など課題は山盛りですね。

2つ目は、数値管理です。
具体的には、肝となる数値を常に取得し続け、いつでもそれを引き出せるように可視化することです。
今のところ、GAとRedshiftとmixpanelやらAdEbisやらで何とか必要最低限のところは押さえられております。
どんどん肥大していくデータですが、実際はもっともっと必要です。

3つ目は、経営的な意味での数値計画です。
サービスにまつわるデータだけでなく、
付随しそうな全てのデータを収集し、来期までの予測をたて、
目標値までストレッチするストーリーラインを考えることです。
これはとてつもなく大事なのに、ものすごく難しいです。

さて、この3つに日夜頭を悩ましていたのですが、
最近すこし僕の中だけで進展がありました。

というのも、
この3つをバラバラに考えるのをやめたのです。
2つ目の数値管理と、3つ目の数値計画は割りかし近そうな領域ですが、
1つ目の「ワークフロー」という「実際の人の動き」までを考慮にしないと、
結局2つ目も3つ目もグダグダになるか、机上の空論になるかしてしまうと思ったのです。
というか、この3つが滞りなく連鎖していれば、 必然的にPDCAらしくなるんじゃないかなと思っています。
そしてこの3つのどれをスタートにしても、
他の2つについての意識を外さないような仕組みになっている、
もっと言えば、
「この3つのうち、どの領域の作業をしていても他の2つが見えている」
という状態せしめれば、
物凄い安心感とともに、セレンディプティやら何やらが沸き立つ脳みその状態にもっていけるんじゃないかな、
ヒソカに思っています。

具体的に言うと、
例えば1つめのワークフロー。
この領域の要は「あるプロジェクトのスケジュールに基づいて効率よく作業する」ということなのですが、
もっと本質的に言えば「全ての作業コミット」は何らかプロダクトに影響を与えるためのものなはずなので、
「自分が行ったコミットがどうプロダクトに跳ね返るのか?」を無視するワークフローなんて有り得ないわけです。
だから、
なんらか作業をしたら、その作業が含まれているプロジェクトの目標数値だったり、
もっと直接的な何らかの数値変化を監視していなければならないわけです。
そういう意味では、ワークフローの終点は「コミットして本番反映!」ではなくて、
「その数値を取得して監視」というところまでが含まれるわけです。

ですが、
その数値を取得して監視、というのは2つ目の数値管理のシステムがしっかりしていないと、
まずそもそも「出来ない」ということになる。
なので2つ目に事件は飛び火しますね。
数値管理は「目的の数値を取得する」だけでなく、
「気持よく可視化する」まで含めたプロジェクトになっていなければなりません。
なので、
ここは面倒臭がらずにとにかくGAでもなんでも、
コンソールだけに頼らず、手元に自由に出し入れできるような形でデータを採取し、
とにかく気軽にデータを閲覧出来るようにしている必要があります。
そして、とても大事なのは、
ここまでの流れ、「この数値はこのコミットが監視しているよ!」というのが、
作業コミットが発生する段階で見えていなければなりません。
もう本当当たり前の話ですが、ちゃんと管理するのは結構難しいと僕は思っています。

そして最後、数値計画です。
数値計画は、前も少し触れましたが、
単なる数値遊びに陥りがちです。
マクロ的な視点で、如何に近似曲線やら適当なパターンを発見しようが、
それだけでは信頼性が担保される訳ではありません。
なので、必ずどこかで「積み上げ」が必要になるはずです。
細かい要素の成長予測を緻密に練り上げていって、
「ここまではイケるはずだ」という信頼性の高い数値予測の土台を作るシーンがきっと必要になると思います。
しかし、
ある日この積み上げ作業を行おうとしても、
数値に関するアセットや、伸び幅に関する現実的な相場観が掴めていなければ、
これらもまた非常に困難な作業になるわけです。
つまり、1つ目と2つ目の連鎖による的確な「作業と数値の跳ね返り」を把握していることが、
数値計画にすっと繋がるわけです。

当たり前のようにしっかり管理しろ、
ということを長ったらしく言ってきましたが、
結局これがしっかりできるということは結構難しいんじゃないかなと思っています。
そしてその原因が、
3つのシステムを構築しようと思った時に、
それらが全てつながることを前提に作成していないことが挙げられるんじゃないかなと思っています。

今、ワークフローから数値管理までをスムーズに繋ぐシステムをなんとかつくろうとしています。
失敗に終わるかもしれませんが、
とにかく、
作ってみてから考えましょう!

それではまた。