Redshiftでの接続アカウント管理 (read-onlyユーザとグループの作成)

背景

Redshiftをチームで使うときにはユーザアカウントとパスワードを共通で使うのではなく個々人に別々に付与するのがセキュリティ的にも好ましいです。 ここでは、どのようにユーザをRedshiftで管理するかの一例を紹介します。

はじめに

Redshiftは接続で使うコマンドなど、PostgreSQLがベースなのでMySQLの管理とは異なっています。 PostgresSQLはpsqlコマンドで接続する際にデータベースを指定します。接続後は、そのデータベースにつなぎにいっていることになり、他のデータベースへのクエリは投げられません。

MySQLmysqlコマンドでサーバに接続後に、データベースをまたいでのselectもできるので、そこはMySQLとは異なった点です。

また、PostgresSQLではデータベースの下にスキーマという概念が存在しており、そのスキーマの下にテーブルを作るイメージです。

postgress

上図はこちらの記事から引用しました。

Redshiftはデフォルトでpublicのスキーマが定義されております。

権限について

Redshiftでは以下の権限があります。各権限の詳細はここに書いてあります。

  • SELECT: SELECT ステートメントを使用して、テーブルまたはビューからデータを選択する権限
  • INSERT: INSERT ステートメントまたは COPY ステートメントを使用して、データをテーブルにロードする権限
  • UPDATE: UPDATE ステートメントを使用して、テーブルの列を更新する権限
  • DELETE: テーブルからデータ行を削除する権限
  • REFERENCES: 外部キーの制約を作成する権限
  • CREATE: データベースの場合は、データベース内にスキーマを作成する権限、スキーマの場合はスキーマ内にオブジェクトを作成することをユーザーに許可する
  • TEMPORARY: 指定したデータベースに一時テーブルを作成する権限
  • USAGE: 特定のスキーマに対して USAGE 権限を付与します。これによって、そのスキーマ内のオブジェクトにユーザーがアクセスできるようになる

まとめると、テーブルをSELECT/INSERT/UPDATE/DELETEする権限はテーブルに紐付き、テーブルを作成する権限はスキーマに紐付きます。 スキーマを作成する権限はデータベースの権限に紐付きます。

各権限を確認するには以下のようにします(testデータベースに接続)。

データベースの権限の確認

select
    datname,
    HAS_DATABASE_PRIVILEGE(datname, 'create') as create,
    HAS_DATABASE_PRIVILEGE(datname, 'temporary') as temporary
from 
    pg_database
WHERE
    datname = 'test';

-- 結果は以下
 datname | create | temporary 
---------+--------+-----------
 test    | t      | t

スキーマの権限の確認

select 
    nspname,
    has_schema_privilege(nspname, 'create') as create,
    has_schema_privilege(nspname, 'usage') as usage
from 
    pg_namespace
WHERE
    nspname = 'public';

-- 結果は以下
 nspname | create | usage 
---------+--------+-------
 public  | t      | t

read-onlyユーザの作成

publicのスキーマの特定のテーブル(test_1)に対して、SELECTとUSAGEのみできるユーザを作成します。

まず、rootアカウントで、test_1というテーブルを作り、データを1行いれておきます。

CREATE TABLE "test_1" (
  "user_id" varchar(20) NOT NULL DEFAULT ''
);
INSERT INTO "test_1" VALUES ('user_1');

その後、同じくrootアカウントで、ユーザを作成します。(テストなのでパスワードは適当です)

-- ユーザの作成と、ユーザへのスキーマの追加
CREATE USER user_ro PASSWORD 'Abcd1234';
GRANT USAGE ON SCHEMA public TO user_ro;

-- SELECT権限をユーザに付与する
GRANT SELECT ON ALL TABLES IN SCHEMA public TO user_ro;

ユーザの権限を確認してみましょう。以下のように正しく付与されています。

select 
    tablename,
    has_table_privilege('user_ro', 'test_1', 'select') as select,
    has_table_privilege('user_ro', 'test_1', 'insert') as insert,
    has_table_privilege('user_ro', 'test_1', 'update') as update,
    has_table_privilege('user_ro', 'test_1', 'delete') as delete,
    has_table_privilege('user_ro', 'test_1', 'references') as references
from pg_tables where schemaname='public' order by tablename;

-- 結果は以下
 tablename | select | insert | update | delete | references 
-----------+--------+--------+--------+--------+------------
 test_1    | t      | f      | f      | f      | f
(1 行)

ただし、この状態だと、user_roはpublicスキーマ以下にテーブルが作れてしまいます。デフォルトではすべてのユーザはPUBLICスキーマに対して、CREATE 権限と USAGE 権限を所有しているためです。 参考

よってまず public スキーマからCREATEの権限を削除し、その後に各ユーザにCREATE権限を付与する必要があります。 参考

-- publicスキーマのすべてのユーザ(PUBLIC)からCREATE権限を削除
REVOKE CREATE ON SCHEMA public FROM PUBLIC;

-- 特定のユーザのみCREATE権限を付与
GRANT CREATE ON SCHEMA public TO {user-name};

まとめると、以下のようにコマンドを実行すると作成できます。 もちろん2人目以降のユーザからは、CREATE USERから実行すれば大丈夫です。

-- CREATE権限をpublicから削除
REVOKE CREATE ON SCHEMA public FROM PUBLIC;

-- CREATE権限が必要なユーザがいるなら各ユーザに以下を実行
GRANT CREATE ON SCHEMA public TO {user-name};

-- ユーザの作成と、ユーザへのスキーマの追加
CREATE USER user_ro PASSWORD 'Abcd1234';
GRANT USAGE ON SCHEMA public TO user_ro;

-- SELECT権限をユーザに付与する
GRANT SELECT ON ALL TABLES IN SCHEMA public TO user_ro;

じつはこのままだと、GRANT SELECT後に新規で作成されたテーブルにはSELECTができません。 解決するには、都度GRANT SELECTを新規テーブルを作成された後にしてやるかグループを使うのがいいと思います。

ユーザの削除

いらなくなったユーザの削除は以下で出来ます。

DROP user user_ro;
ERROR:  user "user_ro" cannot be dropped because the user has a privilege on some object

と、思ったらエラーが出ました。各種付与した権限はとってからでないと削除することは出来ません。 以下のようにすると削除できます。

revoke select on all tables in schema public from user_ro;
DROP user user_ro2;

グループの作成と権限

多くのユーザがRedshiftを使う状態になってくると、ユーザがグループに紐付けて管理したくなります。 ここではグループの作成と権限の付与の仕方を紹介します。 rootでログインし、以下を実行します。

CREATE GROUP public_ro;

-- ユーザの作成
CREATE USER user_ro_2 PASSWORD 'Abcd1234';

-- ユーザをグループに紐付ける
ALTER GROUP public_ro ADD USER user_ro_2;

追加されたか確認してみましょう。

SELECT * FROM pg_group;

-- 結果は以下
  groname  | grosysid | grolist 
-----------+----------+---------
 public_ro |      101 | {105}

IDは数字ですが、所属するユーザ一覧からユーザ名が確認できます。

SELECT * FROM pg_user WHERE usesysid = 105;

-- 結果は以下
  usename  | usesysid | usecreatedb | usesuper | usecatupd |  passwd  | valuntil | useconfig 
-----------+----------+-------------+----------+-----------+----------+----------+-----------
 user_ro_2 |      105 | f           | f        | f         | ******** |          | 

この状態でuser_ro_2でログインし、selectをしてみると、期待どおりできない事がわかります。

再度、rootユーザでグループにSELECT権限を付与してみます。

GRANT SELECT ON ALL TABLES IN SCHEMA public TO GROUP public_ro;

user_ro_2でログインし、selectできることを確かめます。

グループからユーザの削除

ユーザがプロジェクトを離れた場合などはグループから削除する必要があるので、以下のようにします。

ALTER GROUP public_ro DROP USER user_ro_2;

グループの削除

DROP GROUP public_ro;

BigQueryのWeb UIでテーブル名が長すぎて確認できないときの対処法

BigQueryを使っているとどうしても長いテーブルを作る必要が出てくるかもしれません。 その際にクエリブラウザで見てみると以下のように長いテーブル名は省略されてしまいます。

table_name.png

その際に便利なのが、StylebotというChromeのExtensionです。 これを使ってCSSを変えれるので、左ペインの幅を広くして、より多くのテーブル名を見せる事ができます。

Stylebotの設定

以下のように設定すれば左ベインの幅が広がります。

#content-panel

css_1.png

#content-panel-main

css_2.png

div.project-display

css_3.png

div.tables-table-id.goog-inline-block.overflow-ellipsis

css_4.png

結果

result.png

綺麗に広がりました!まだ全体は見えませんがここらへんはCSSを調整すればいいかと思います。

Apacheにかわるwebサーバ: uWSGIパフォーマンスチューニング

背景

PythonDjangoでソマートフォンゲームのアプリケーションサーバを開発しており、そのwebサーバとしてuWSGIを使っています。 uWSGIには多くのパラメータがありすぎてどれを選んでいいかわかりにくいです。

実際に負荷試験をして、各種パラメータを変え、安定的にパフォーマンスが出せるようになったので、 そのときにどのように計測して、どのパラメータを変えたのかを共有したいと思います。

環境

server.png

性能測定ツール

「推測するな、計測せよ」

という言葉がありますが、何をおいても計測できなければ改善したかどうかわかりません。 主に以下のツールが今回役立ちました。

  • NewRelic: おなじみですね。有償版なので細かいところまで見れます
  • uwsgitop: PyPIで導入できる、uWSGIのパフォーマンス統計ツール
  • vmstat

uwsgitopについて

uWSGI側の設定で以下のようにして、パフォーマンス統計データをsocketに出力できます。

stats = /var/run/uWSGI/projectname.stats.sock
memory-report = true

これをpipなどでインストールしたuWSGItopを以下のように実行すると統計値がunixコマンドtopのようにリアルタイムで見れます。

$ uwsgitop /var/run/uWSGI/projectname.stats.sock

以下が実行例です。この状態ではプロセス単位ですが、キーボード上でaを押すと、スレッド単位で見ることもできます。

uwsgitop.png

今回設定したパフォーマンスチューニングに有効なuWSGI設定

uWSGI Optionsに各種設定ファイル用の値がかいてあるのですが、設定出来る量が多すぎてどれを設定していいか最初はわかりずらいです。 さらに、オプションの説明も簡易的で、uWSGIの作者自身もソースみてねといっているので使ったことがない場合には難儀します。

ここでは実際に設定してみて効果があったパラメを上げたいと思います。

processes, threads

uWSGIはリクエストを受け付けるプロセスとスレッドの数をそれぞれ指定できます。 開発しているuWSGIには以下のように設定しました。

processes = 16
threads = 1

様々なプロセス数とスレッド数の組み合わせで試験したのですが、threadsを増やすとコンテキストスイッチが多くなりさばけるRPSが半分以下になっていました。

vmstat_1.png


vmstat_2.png

ちなみにthreadsが1の場合に、processesを増やしてもコア数である8以上では大して違いはありませんでした。

thunder-lock

Linux系のサーバを使っているのならまずこのオプションを以下のようにtrueに設定すべきです。

thunder-lock = true

詳しくはここにかいてあるのですが、falseになっていると複数のuWSGIのプロセスで捌くリクエストに偏りが出てしまいます。

uwsgitop_1.png


uwsgitop_2.png

max-requests, max-requests-delta

max-requestsは、プロセスが再読み込みするまでにどのくらいのリクエストを受けるかという設定値です。 以下のように設定してあります。

max-requests = 6000

負荷試験当初はこの値が大きな値になっており、再読み込みされず、メモリの使用状況を見ると以下のようになってました。

memory_1.png

uWSGIプロセスがかかえているメモリの増え方などを見て、6000が適切なのでそのように設定しました。 どうしてメモリが増大していくか別途調べる必要はあるとは思いますが、6000回に1回の再読み込みなのでそう影響がないと判断し設定しています。 再読み込みするとメモリは開放され、初期に起動したときと同じ状態になります。

プロセスごとのを取り忘れていましたが正しく設定されると以下のようにメモリが一定期間で落ち着きます。

memory_2.png

ただ、ここで注意なのですが、プロセスが再起動すると数秒間、新しいリクエストが受けれなくなります。 max-requestsという同一の値をすべてのプロセスに適用すると、ほぼ一斉に再起動するので、サーバ全体でリクエストが数秒うけられなくなります。

これを回避するのがmax-requests-deltaという値で以下のように設定しています。

max-requests-delta = 300

プロセスごとにこの差分で再起動してくれます。例えばある1プロセスが6000で再起動する場合は、次のプロセスは6300のリクエストを受けると再起動します。 RPSが16くらいでプロセスが16の設定を想定していれば、1プロセスが1秒ごとに1リクエストうけるので、300秒ごとくらいに再起動します。 このようにすると一度に再起動するプロセスが限られるのでサーバ全体としてリクエストがうけれなくなることは回避できます。

touch-reload, lazy-apps

touch-reloadにファイルのパスを指定し、その設定がtouchされるたびにuWSGIをリロードすることができます。 ただそうすると、サーバ全体でリクエストを受けれなくなってしまうので、lazy-appsを設定し、順次リロードできるようにできます。

自分たちの環境ではlazy-appsを指定すると、すぐ更新したい場合などは不向きなので、数秒の待ちは許容し設定してません。

まとめ

今回、実際にチューニングしたuWSGIのパラメータを見てきました。 その他にも以下のようなパラメが設定してありますが、これからもより深く調べ性能改善していきたいと思います。

  • listen
  • harakiri
  • harakiri-verbose
  • limit-as
  • log-date

踏み台サーバ越しにあるMySQLにSequel Proでつなぎにいく

背景

Sequel ProはMySQLGUIでいじれるのでいろいろ便利です。 もちろんSQL生で叩いてもいいですが、効率面からもSequel Proのほうが早かったりします。 以下は、Sequel Proの画面です。

gui.png

ローカルにあるMySQLは簡単につなげるのですが、その時に困るのが、踏み台など経由した先にあるMySQLにつなぐ場合です。 この場合、以下のように設定すると繋げれるようになります。

環境

server.png

ローカルのMacからAppサーバであるApp001に、踏み台を経由して以下のコマンドで、つなぎに行けることを前提としています。 なおapp001.xxxはApp001のホスト名です。

ssh app001.xxx

上記のようにつなぐには~/.ssh/configに以下のような設定をします。 fumidai.domainが踏み台のホスト名です(図ではHost: Aのこと)

Host fumidai
    HostName fumidai.domain
    User user_name
    IdentityFile ~/.ssh/id_rsa

Host app001.xxx
    User user_name
    IdentityFile ~/.ssh/id_rsa
    ProxyCommand ssh fumidai -W %h:%p

Sequel Proの設定

以下のように設定します。

sequel_pro.png

注意

このようにすればSequel Proで本番サーバにつなげたりしますが、念のため、アカウントはRead Onlyで設定しておくといいです。 なんでもできるアカウントだと間違って行を消したときなど取り返しがつかない事になるからです。

詳解 NewRelic で監視&性能改善

概要

1年半ほどNewRelicを本番環境+開発環境で使ってきて知見が溜まってきたので共有したいと思います。 ここで説明している機能は有料版のものも含みます。

NewRelicとは

overview.png

NewRelicとはサーバ、またはアプリケーションの状態をモニターし、その性能を改善するために使われるツールです。 既存のモニタリングツールとしては、zabbix, ganglia, nagios, munin など各種ありますが、NewRelicが優れているのはその手軽さかと思います。 インストールしたらアプリケーションをサーバ運営する上で必要なメトリックスが一通り揃っています。 既存のモニタリングツールだとインストールするユーザが必要なメトリックスを定義して設定、場合によってはスクリプトを書かなければいけません。 その点、NewRelicはデフォルトのメトリックスが非常に充実しており見やすく配置されており追加設定なしで十分という場合も多いでしょう。 既存のメトリックスにない場合でも手軽にインストールできるプラグインが充実しております。

この記事ではNewRelicの誰でもしっている機能から、有料版の細かい機能までをケーススタディ別で紹介したいと思います。

前提環境

スマートフォンゲームのアプリケーションサーバを開発してます。 NewRelicでメトリックスを取っているアプリケーショの環境図は以下です。

server.png

  • AWS環境
  • アプリサーバは複数台でEC2に乗っているDjango (python)のアプリケーション
  • MySQLとRedisにアプリサーバが繋がっている

と、ごくごく一般的な構成です

それではサーバエンジニアのケーススタディを始めます

ケース1: アプリケーションの応答が遅いけどもっと早くならないか

いろいろな人から言われると思います。ざっくりすぎてよくわからないので、まず問題を定義するところから始めます。 遅いところはどのAPIなのか。いつから遅くなったのか。特定の場合のみ遅いのか。他のユーザはどうなのか。 たくさんありますが、何が問題なのかを具体的にします。その結果以下のような問題がわかりました。

  • ガチャのAPIが1日まえくらいから遅くなった。他のプレイヤー全員が遅いわけではなく、早い人もいる。

だいぶ具体的になったので、NewRelicを見てみます。 APPSで該当のアプリケーションを選んでから、Transactionsという項目を押してください。 「Slowest average response time」というものを選ぶと応答時間の順に遅いAPIがわかります。 (注意: 全体的に遅いですが、まだ性能改善前で、サーバのチューニングもしていないのです。。。)

gacha_transaction.png

そこのgachaのクリックすると右側に以下のようなページが見えます。

gacha_select2.png

このページを見ることによって以下の事がわかります。

  • pythonコードのFunctionで多くの時間を取っている
  • unit_player_xxのselectが多い
  • unit_player_xxのinsert, updateも多い

問題定義の内容とソースコードの両者を合わせてボトルネックを探ると以下の点が問題でした。

  • 大量にユニットを所持しているユーザのレスポンスが遅かった => ユーザの取得済みユニットの全リストをAPIで返しているが必要ないので削除
  • ガチャで取得したユニットごとに複数のinsert/udpateが走っている => 更新系はbulkで行う

上記の対応をすることによりAPIが早くなり問題ない応答時間になりました。 このようにNewRelicではAPIごとのSQL発行数, Redisへのクエリ発行数, pythonコードの実行時間が取得で性能改善に役立ちます。

ただ、ここで注意しなければならないのは、Avg timeはあくまでかかった時間なので、サーバのCPUがいっぱいいっぱいだと、pythonコードが処理できずコードの時間が長くなったりします。

ケース2: MySQLがなんか遅そうなのだけれどもどこが原因?

NewRelicのMySQL項目を説明するためのケースのようですが、実際に起こり得ます。 ユーザが増えてきた際にAppサーバのCPUは50%くらいで問題なさそうなのになんかおそくなったという際はMySQLかRedisが原因かもしれません。

よくわからないときは基本のOverviewを見ています

mysql_slow.png

なんだかMySQLが遅そうですね。そのようなときは、左ペインDatabasesを選択し、ひとまず以下の項目を見てみます。 (注意: 別の時間のものです。単に紹介なので)

databases.png

クエリごとの応答時間がわかるので、遅くなったクエリなど一目瞭然です。 このケースでありがちなのは、データの履歴が少なかったときは早かったのですが、多くなってくると遅くなるパターンなどです。 インデックスの貼り忘れだったり、そもそも履歴が必要なかったりするケースがあったりするのでそこを直します。 それぞれのクエリをクリックするとそのクエリを発行しているAPIもわかるので改善により役立ちます。

この項目ではクエリ単位でしか見れませんが、MySQLのサーバ自体のメトリックスをみたい場合は、MySQL pluginがおすすめです。 (注意: 別の時間のものです。単に紹介なので)

http://newrelic.com/plugins/new-relic-platform-team/52

インストールすると以下のような項目が見れます。

plugin_1.png plugin_2.png plugin_3.png

ケース3: CPUがいっぱいいっぱいになっているがなにがおこっているのか

どのプロセスがCPUをくっているのか知りたいときもありますがAWSコンソールの標準のメトリックスでは全然わかりません。 そんなときもNewRelicならdefaultでインストールしたエージェントでとれます。

トップペインからSERVERSを選びます。Processesを左ペインから選ぶとどのプロセスがCPUを多く使っているかわかります。

servers_1.png servers_2.png

ケース4: いつデプロイしたのか知りたい

NewRelicのWeb APIにイベントを投げる事によってデプロイした時間にマークをつけることができます。

deploy.png

ケース5: リリースしてからてんやわんや

なんだかよくわからないケースですが、本番サーバにしかNewRelicをいれていなかったというお話です。 NewRelicは開発期間中に開発サーバにいれてこそ効果が発揮されます。 よくあるのは開発で早く動いていても本番になると性能が劣化するパターンです。開発環境では十分な負荷がかかっていないので、SQLのクエリが遅かったりすることろがわかりません。 そのような際は開発環境にもNewRelicを入れておき、APIごとのSQL発行数などを監視しておきます。 もちろん負荷試験をリリース毎にやればいいのですが、コスト・時間的に現実的ではない場合も多いです。 月々多少の費用はかかりますが十分ペイできると思います。

ケース6: アプリケーションが正しく動いているのか知りたい

ようするに生存確認です。正しくやろうとすると、一通りのAPIにリクエストを投げてレスポンスを確かめます。 ただ、実際にはそこまでする必要はなくアプリケーションが動いているかどうかを1つの生存確認用のAPIに投げてレスポンスがただしいかどうか確かめればいいと思います。 その際に、どのようなAPIを作るかが大事です。echoサーバのようにただechoを返すのではなくMySQL, Redisなど繋がっているサービスにも軽いクエリをなげるといいです。 その様にすることによりMySQL, Redisの生存確認も同時にすることができます。

NewRelicでは以下で設定できます。

ping_1.png

設定したあとはAvailabilityでその結果を見ることができます。

ping_2.png

Alertメールなども設定できるので、設定しておくとシステムダウンの際に素早く気づくことができます。 自分の所属しているチームでは、開発環境が接続できなくなったときなどチャットに通知がとどくので素早く気付き修正することができます。

ケース7: 世界各国からの応答時間を知りたい

世界展開しているアプリは、各国からの応答時間がきになるものです。 NewRelicではSYNTHETICSを設定することによって以下の地域からの応答時間を調べることができます。 一定時間ごとに送ってくれるます。

synthetics_1.png synthetics_2.png

ケース8: 例外が発生したときにそのプレイヤーIDが知りたい

NewRelicでは発生した例外はErrorsで表示されるのですが、自分で設定しない限りはアプリケーション特有の情報は含んでくれません。 例えば、player_idなどユーザを特定できるものが例外とともに記録されていればアプリケーションの管理画面などからそのユーザを検索し、例外のより詳しい状況がわかることができます。

NewRelicで正しく設定すると以下のように見れます。

custome_attribute.png

ソースコード上では以下のように設定しています。 共通処理なので、decoratorとかviewの前処理などに仕込めばいい感じにしてくれそうです。(Djangoでのお話)

# newrelicにplayer_idを追加する
newrelic.agent.add_custom_parameter('player_id', player.id)

ケース9: あるAPIを改善したので実際に早くなっているのか確認したい

改善したならば計測して実際に早くなっているか確認しないと意味がないですね。 NewRelicでその辺も確認できます。

historical_performance.png

ケース10: ある特定のAPIが遅いがソース上でどこが遅いのか確認したい

その1のケース1で遅いAPIのざっくりどこで時間をとっているかわかりました。

しかし、もっと細かくソースコード単位でどこの処理で時間がかかっているのか見たい場合もあると思います。 その時に活躍するのが、Key TransactionsX-Ray Sessionsです。

Key Transactionsは、特定のAPIごとに、リクエストを別ページで追跡して詳細なログを見ることができます。 その特定のリクエストのプロファイラを表示してくれるのが、 X-Ray Sessionsです。


それでは設定していきましょう。

今回は、/api/homeのAPIのパスをKey Transactionsとして追加してみようと思います。 以下のように①=>②=>③の順番でクリックします。②で気になるAPIをクリックして追跡します。今回の場合だとhomeのAPIです。

transactions.png

/api/homeのKey Transactionが出来るので、ウィザードに従いKey transactionsのページへ移動して見てみます。 このように特定のAPIのリクエストのみの情報が見れます。

key_transactions_1.png

Key transactionによってAlertなども設定できますが、今回は、X-Rayで処理のボトルネックを調べてみます。

x_ray_1.png

x_ray_2.png

これでX-Rayが設定できました。sampling_homeという名前で、最大1時間にわたって、50リクエスト追跡します。 アクセスがあるサーバならしばらくまつか、APIテストなどを該当のAPIにリクエストして50リクエストたまるのを待ちます。

たまったらsampling_homeを開いて、X-Rayをクリックし、Thread Profileを開いてみます。 実行された順番ごとにかかった時間のパーセンテージがのっているので詳しく、ボトルネックを見ることができます。(結構モザイクばっかりで見難くてすいません) ただし注意しなければいけないのは、IO待ちやコンテキストスィッチなどでCPUが切り替わったときに待っている待ち時間もここに反映されているので参考程度にという形ではあります。

x_ray_3.png

おまけ: たまたま遅いリクエストの原因を追求する

Key Transactionsにはもう1つ便利な機能があって、トラックしたリクエストの1つ1つの詳細を応答時間に応じて見ることができます。 これを使えば、多くのリクエストは早いけれども、時々遅いものがあるなどの場合を発見しやすく、その特定のリクエストだけをフォーカスして、どこの処理が遅くなっているか見ることができます。

さらに実行された SQL も細かく見れるので障害対応や遅いクエリの対応にかなり役立ちます。

x_ray_4.png

hubotをHipChatと連携させる + Backlog, Stashから情報を取得してHipChatになげるcronjobを実行

背景

  • 会社でBacklogを使っているが、HipChatに通知を流したい
  • 会社でStashを使っているが標準のHipChat連携機能ではPull Requestをしても通知が来ないので通知するようにしたい。
  • 楽しいボットを作ってみたい

ゴール

  • HubotをHipChatにつなげる
  • HipChatに地獄のミサワの画像をランダムに表示させる
  • HubotとBacklogを連携させる。バックログの特定のカテゴリ
  • 定期的にHubotがHipChatにつぶやく
  • Hubotにshellを実行させる
  • StashのPull Requestが作られたらHubotを使ってルームに通知を送る
  • Hubotをデーモン化する

環境

インストール

公式ドキュメントを参考にしながらインストールを行う

node.jsとnpmのインストール

$ brew install node
$ node -v
v0.12.2

$ npm -v
2.11.0

hubotのgeneratorをインストールする

$ npm install -g yo generator-hubot

generatorでHubotのプロジェクトを作成する

任意のディレクトリに移動し、以下を実行
$ yo hubot

名前はwapa5powに
? Bot name: wapa5pow

HipChatと連携させたいので、adaptorはhipchatとして実行する
? Bot adapter: hipchat

実際に動かしてみる

$ ./bin/hubot

ボットの名前を忘れずに打つ
wapa5pow> wapa5pow help
wapa5pow adapter - Reply with the adapter
wapa5pow animate me <query> - The same thing as `image me`, except adds a few parameters to try to return an animated GIF instead.
wapa5pow echo <text> - Reply back with <text>
wapa5pow help - Displays all of the help commands that wapa5pow knows about.
wapa5pow help <query> - Displays all help commands that match <query>.
wapa5pow image me <query> - The Original. Queries Google Images for <query> and returns a random top result.
wapa5pow map me <query> - Returns a map view of the area returned by `query`.
wapa5pow mustache me <query> - Searches Google Images for the specified query and mustaches it.
wapa5pow mustache me <url> - Adds a mustache to the specified URL.
wapa5pow ping - Reply with pong
wapa5pow pug bomb N - get N pugs
wapa5pow pug me - Receive a pug
wapa5pow the rules - Make sure wapa5pow still knows the rules.
wapa5pow time - Reply with current time
wapa5pow translate me <phrase> - Searches for a translation for the <phrase> and then prints that bad boy out.
wapa5pow translate me from <source> into <target> <phrase> - Translates <phrase> from <source> into <target>. Both <source> and <target> are optional
wapa5pow youtube me <query> - Searches YouTube for the query and returns the video embed link.
ship it - Display a motivation squirrel

HubotをHipChatにつなげる

HipChatのHubot Adapterを参考にしながら設定する

HipChatで新しいユーザを作り、ここXMPPの情報を確認する。

以下のように実行する(アカウント、パスワードは適宜読み替える)

HipChat用の環境を設定
$ export HUBOT_HIPCHAT_JID="111111_11111111@chat.hipchat.com"
$ export HUBOT_HIPCHAT_PASSWORD="1234567890"

起動
$ bin/hubot -a hipchat

好きなチャットルームに移動して、作成した新しいBot用HipChatユーザのメンションをつけて発言する

@wapa5pow ping

そうするとPONGが帰ってくる

HipChatに地獄のミサワの画像をランダムに表示させる

Hubotをインストール、hipchatと連携し、foreverでデーモン化(CentOS6.4)を参考にしてミサワをHipChatに表示させる

定期的にHubotがHipChatにつぶやく

こちらを参考に設定できます

Hubotにshellを実行させる

こちらを参考に、以下のファイルを作成し、scripts以下に配置する。 HipChatでcalendarと呼びかけるとカレンダーを返す

child_process = require('child_process')

module.exports = (robot) ->
  robot.respond /calendar$/i, (msg) ->
    child_process.exec 'cal 2015', (error, stdout, stderr) ->
      msg.send(stdout)

HubotとBacklogを連携させる。バックログの特定のカテゴリを取得する

Backlog API 課題一覧の取得を参考にしてリクエストを組み立てそれをpythonスクリプトにしました。 HubotでCoffeeScriptでつくろうと思ったのですがpythonでつくりそれをcronで呼ぶほうが早そうだったのでそのようにしました。

StashのPull Requestが作られたらHubotを使ってルームに通知を送る

Stash APIを参考にしてpythonスクリプトで作った。

Hubotをデーモン化する

こちらを参考にする

ディレクターがゲームのマスターデータをSourceTreeを使ってgitで管理するときに使えそうな差分確認ツール

背景

  • 自分が関わっているスマフォゲーム開発で使える
  • ゲームのマスターデータをSourceTreeを使ってGUI上で、git管理したい
  • ディレクターの方はWindowsを使っているのでWindowsで使えるツール
  • 日本語のデータも扱える
  • 無料で使える
  • 行単位ではなくワード単位でdiffがわかる。見やすい。

tl;dr

KDiff3でよいのでは

調査内容

SourceTreeの設定で使えそうなdiffツールがリストアップされているが、その中で無料で、windows/mac両方とも使えるツールを調査した。

  • DiffMerge
  • KDiff3
  • P4Merge

SourceTreeは「環境設定」=>「Diff」=>「差分表示ツール」から様々なdiffツールが選べる。

f:id:wapa5pow:20150517122201p:plain

その後、以下のように外部 Diffとしてツールをよびだせる。

f:id:wapa5pow:20150517122155p:plain

SourceTreeのみの場合

以下のようにdiffがワード単位でないのですこぶるわかりにくい

f:id:wapa5pow:20150517122338p:plain

DiffMerge

文字化けですorz... 環境設定から日本語フォントを設定できそうでしたがボタンを押したら落ちたのであえなく候補から脱落。 英語のみだと結構見やすくてよかったので、日本語が設定できるならいいと思います。

f:id:wapa5pow:20150517122153p:plain

KDiff3

日本語もばっちり表示されております。やや色が見にくいですが色設定すればいけそうです。

f:id:wapa5pow:20150517122200p:plain

P4Merge

合田剛のところがdiffとして出ていないのとなんだか高さがずれてそうなのでうまく使えなさそうです。

f:id:wapa5pow:20150517122159p:plain