技術サポートするときに気をつけている5つのこと

株式会社fluctのエンジニア長谷川です。

弊社はフルスクラッチで開発,提供をしているfluct SSPというプロダクト以外にも、Googleの認定パートナーとしてGoogleのプロダクトを利用したメディアのマネタイズのお手伝いも行っています。主なプロダクトはGoogle AdSenseDoubleClick AdExchange, DoubleClick for Publishersです。

これらのプロダクトは非常に高機能な反面、効果的に活用するにはネット広告一般やプロダクト自体に関する高度な知識が不可欠です。そこでfluctがプロダクト運用のお手伝いをしています(詳しくはこちら)。

私のfluctでのミッションとして、Googleの商材の技術的なサポートというものがあります。具体的には…

  • コンサルティングサポート
    • お客様あるいは弊社コンサルのアイディアのフィジビリティ調査
    • アドが出ないなどのトラブル対応
  • 運用サポート
    • レポーティングツール開発
    • 広告運用のシステム化検討及び開発

コンサルティングサポートはお客様のアドテクに関する知識レベルややりたいことは多種多様であるため、相手の意図を正しく理解し、かつこちらの意図をいかに正しく伝えるかが重要となってきます。

このミッションに携わってほぼ1年近く経ち、ちょうどブログ記事を書く機会を得られたのでせっかくなのでこの仕事をする上で心がけていたことをメソッド集という体で書いてみたいと思います。

目次

メソッド1: 相手の話を自分の言葉で再翻訳する

以前同僚に「あなたは相手の意図を確認する習慣があって、それがとてもよい」と指摘されたことがあります。あまり意識せずにやってたのですが、言われてから意識的にやるようになりました。

みんなではじめるデザイン批評」という書籍ではこれを「アクティブリスニング」と紹介されています。会話例がとても良かったので引用します。

アクティブ・リスニングには、受けたフィードバックに対してことばを返すときに、相手の話を別のことばに言い換えて繰り返すというやり方がある。そうすればフィードバックを与える側は、私達の理解と自分が伝えたいポイントとが一致しているかを確かめることができる。以下に例を示す。

製品のオーナー「スクリーン上のニュースフィードの配置が気になります。とても目立ちますが、実際に顧客がそれほどひんぱんに使うとは思いません。」

デザイナー「わかりました。私の理解が正しければ、心配なのは、あまり使われないかもしれないニュースフィードが注目を引きすぎて、ユーザーの注意が他のもっと重要な要素からそれてしまうのではないか、ということですね?よろしいでしょうか?」

製品のオーナー「はい、顧客の使用頻度の高いものに、より高い優先順位をつけられるよう、別の処理の仕方を検討するべきです。」

理解が正しくない場合は、さらに明確にするためにフィードバックを掘り下げる質問をすればいい。

「ニュースフィードが目立つという心配について、もう少し詳しく説明していただけますか?」

あるいは、

「わかりました。その点をもう少し考えてみましょう。このまま目立たせておいたとしたら、どうなるでしょうか?」

(「みんなではじめるデザイン批評」 158ページより。一部編集)

アクティブリスニングは相手に対して「私はあなたの話を聞いています」という姿勢を見せると同時に話者の中でも理解できたこと、わからなかったことを整理するのに役立ちます。これは次節で紹介する「目に見える形」とセットでやっています。

メソッド2: 目に見える形で共有しながら話をする

人間、あれとこれを話そうと考えていてもいざ会話を始めると必ず漏れが発生します。それを防ぐには喋っている内容を即時文字にして目に見えるようにすることです。

- 起こっていること
    - XXで広告タグを追加設置したが広告が出ない
- いつから
    - 昨日の夜ぐらいから
- 誰が観測したか
    - メディアの閲覧者からメールで連絡があり、我々に問い合わせが来た
    - 現在もタグが貼られているので我々でも確認は可能

こんな風に、聞き手がテキストを起こすのと同時に、情報が足りない箇所や深掘りしたいところを都度質問していき内容を増強していきます。あとはこれをそのままissueトラッカーに貼り付ければトラッカーベースでやり取りしていけます。

この方法は特にトラブルが発生した時に以下のような効果があると思います。

  • 一緒にトラブルを解決しよう、という姿勢により報告者を落ち着かせられる
  • 余裕がない状況でも思考を整理できる

メソッド3: 思考をまとめるための自分のベストツールを揃える

自分の中で思考を目に見える形で整理する方法を確立しておきます。日頃から可視化するようにしておくと、前述の相手との状況の可視化をするためのトレーニングにもなります。これはデジタルでもアナログでも構いません。

なお、私はevernoteなどのメモツールを挑戦してみましたがどうしてもしっくり来なくてノート + ペン というオールドスタイルで落ち着いています。

弊社でよく目にするツールはこのノートとホワイトボードが一体化したノートです。ちょっとしたお話を図にして共有するのに使っているようです。

私はアピカの方眼紙のノートがお気に入りです。ノートに1500円…と驚く方もいますが、このノートは紙質がとても良くて、メモを書いてて気持ちが良いのです。

f:id:hasegawas:20170713113654j:plain

このようにキーボードの前に置いて、考え事する時はノートにひたすら書いて、コードを書いてるときはディスプレイを見てっていう風に仕事をしています。(実際にメモが書いてるページは業務内容そのままだったので真っ白のページにしています…)

メソッド4: お客様とのミーティングに同行し積極的に発言する

自社プロダクトをサーブしている会社だとエンジニアはなかなか表に出てこない存在になりがちですが、案件の難易度によっては自らお客様との打ち合わせに同行することを願い出ます。これは以下のような効果があります。

  • 関係者が多い場合に伝言ゲームにならないようにすることができる
  • 自分の中の経験を増やす効果がある
    • 会社によってまるで文化や共通言語が違うことを体感し、コミュニケーションの仕方の手札を増やすきっかけとなる
    • 勉強会だと文化が似ている会社の人が集まりがち

メソッド5: 常に機嫌よくいる

最後は精神論かよ…と言われてしまいそうですが、これが一番大事だと思います。トラブルが発生した!!って言う時もその状況を面白がれるぐらいのメンタルが欲しいです(ライトな雰囲気は報告してきた相手の気持ちも落ち着かせる効果があると私は思っています。)

  • 優れた,面白いアイディアは機嫌が良い人に集まってくる
    • 思いついたことを気軽にSlackに投入できてそれ面白いねって反応が出るぐらいだとよい
  • 機嫌が悪いと「話しかけないでおこう」という雰囲気が出来てしまい、聞けば即時解決できたトラブルが後回しにされてしまう
    • その結果また機嫌が悪くなるという悪循環

また、話を聞いた時にそれ前も同じことあったよね、と突っ返さないのも大事です。話しかけにくい、機嫌が悪いって思われて損です。トラブルが終わって落ち着いたときの振り返りにしれっと話してみるのがよいと思います。

まとめ

以上、1つ1つは小さなことかもしれませんがコミュニケーションを円滑にするためのあなたのヒントになればと思います。

この記事を読んで弊社に興味を持ったあなた、ポジションを用意してお待ちしております!もちろん、その他のポジションも用意しておりますので興味があったら是非ご応募を!(露骨な宣伝)

チーム状態をスムーズに変えて障害対応のコストと精神的負荷を抑える

こんにちは。 @at_grandpa です。普段はバッチを書いたりメンテナンスをしています。

今回は、先日起きた障害対応の時、チームの状態をスムーズに変えることで対応コストと精神的負荷を抑えられた、ということを書きます。

 

目次

障害発生

先日の朝に「レポートの数値がおかしい」という連絡がきて確認したところ、とあることが原因で、バッチの自動実行が約半日行われていないことがわかりました。

 

f:id:at_grandpa:20170713114354p:plain:w400

 

普段の対応

普段の対応は以下のような形です。

  1. エラー発生をSlackの全体チャンネルで報告
  2. バッチ系チャンネルにて、考えや現状を垂れ流す
  3. わからないことがあれば有識者にメンションを飛ばす
  4. 実際に叩いたコマンドをどんどんSlackに書き込む
  5. 対応完了を全体チャンネルで報告
  6. チケットにまとめる

小規模なエラーの場合は上記の対応で事足ります。この方法のメリットは以下です。

  • 対応は一人ででき、他のメンバーのコストが発生しない
  • Slackに垂れ流すことでプチレビューの役割を果たす
    • 精神的負荷が多少軽減される
  • Slackにコマンドの履歴が残る

しかし、しばらく運用していると、デメリットが大きくなってきました。

  • 「一番知っている人はat_grandpa」という理由からか、指摘されることが少なくなった
  • 上記が理由で「孤独感」が強くなった
  • 孤独感から「この対応で大丈夫か?」という気持ちが生まれ、精神的負荷が増える
  • 対応方法が伝授されない
    • 記録はあるが、他のメンバーが同じ対応をできるかと問われるとなかなか難しそう
    • 実践で行わないと自信を持って対応することは難しい

信頼されることは嬉しいですが、この信頼はチームを腐敗させます。今までは「対応すること」を優先で行ってきましたが、実際はチームの動きを鈍らせてしまう原因になっているのだと気付きました。この点は反省すべき点です。(自分の共有方法やドキュメント記述方法にも問題があります。それはまた別の問題として認識します。)

しかし今回、新しいアプローチで障害対応を行ったところ、上記の懸念点も解決し、かつスムーズに対応が行えたので、ブログに記録したいと考えました。

 

今回の対応

今回の対応の流れは以下です。

  1. 原因究明と現状把握
  2. 関係者が会議室に集まる
  3. 対応用Slackチャンネルを開設
  4. ペアワークで実対応
  5. 落ち着いたら自席&Slackコミュニケーションへ移る
  6. 対応完了の確認と報告・チケットまとめ

一つずつ見ていきます。

原因究明と現状把握

あるバッチがエラーを吐くことはたまにあるのですが、今回は約半日動いていません。普段と異なる時間帯に数十のバッチを手動で叩かなければなりません。普段と規模が違います。

関係者が会議室に集まる

流石にひとりだと荷が重いと判断し、バッチ周りに触れたことのある新卒2年目の @saxsir256(以下@saxsir)と新卒1年目の@__himu__(以下@himu)にリカバリタスクをお願いしました。と、そこで以下の提案がきます。

f:id:at_grandpa:20170713085202p:plain

これはなるほどと思いました。関係者がガッと会議室に集まることで、以下のメリットがあります。

  • メイン対応者が明確になる
    • メインの対応者が明確でないと、チーム全体が「何かしないといけないのかな。。。」と不安定な状態になってしまいます。これを阻止するためにも「今回はこの3人で対応します」と名言できたのは良かったです
  • 初動が重要な場面で対面コミュニケーションできる
    • Slackは便利ですが、対面コミュニケーションの速度には敵いません
    • 初動の場面でスピーディに共有・方針決定できたのは大きかったです
  • 精神的負荷の軽減
    • 障害対応の初動は何かと不安が大きいですが、対面でのやり取りは精神的負荷をかなり抑えます

実際、この判断はとても良く、自分も把握しきれていないバッチを@himuに解読してもらいつつ、@saxsirと共にホワイトボードを用いて対応スケジュールを組み立てました。わからないことはすぐに共有、わかる人とペアワーク、という軽快な動きが可能でした。

対応用Slackチャンネルを開設

対応用Slackチャンネルの開設は、社内でも一時期話題になっていましたが、実際にメインの運用にはなっていませんでした。自分ひとりの対応の時に、試しに開設したりしていましたが、メモ程度の役割にしかなっていませんでした。しかし今回は3人がメイン対応者です。対面コミュニケーションのスピードは良いですが、記録を残すことも重要なので、とにかく、

  • 実行したコマンドとその結果
  • 現在何をしているかを投稿(他の外部メンバー向け)

を書いていきました。「このチャンネルで対応実況しています」ということを全体チャンネルで発言することで、続々と覗きにくる方が増え、メモ&外部共有が両立できたのは大きかったです。

ペアワークで実対応

先程も書きましたが、会議室に集まることでペアワークが可能となり、精神的負荷を抑えることができました。かつ、対応のちょっとしたノウハウなども詳細に伝えることができたり、実際にコマンドを叩く経験ができるため、今後の対応への自信につながるというメリットもあります。実際、自分でも詳細を知らないバッチを@saxsirと@himuが解読してくれ、それをSlackに残してくれているのでとても助かりました。

落ち着いたら自席&Slackコミュニケーションへ移る

バッチを順に叩いていきDBの状態を確認、次のバッチへ・・・という作業を続けていくと、「依存関係はもう無いし、後は順に叩いていくだけ」という場面になりました。この段階で会議室に集まっているメリットはもうあまりないと判断し、「自席に戻って他のタスクを行いつつ、Slackにて共有」という形に移りました。このようにチーム状態を変えたおかげで、午後からは他タスクに移ることができましたし、ちゃんとSlack上での確認も行え、無事対応を終えることができました。

対応完了の確認と報告・チケットまとめ

対応完了を全体チャンネルに報告し、チケットにまとめます。チケットへのまとめは、Slackの対応用チャンネルの重要部分のリンクを貼るだけです。まとめ直すのは結構コストが高いので、実対応が記録できる対応用チャンネルは便利だなと思いました。

 

まとめ

今回の対応は、以下の点がよかったと思います。

  • メイン対応者を明確にすることで、他メンバーのコストを抑えられた
  • 対応用Slackチャンネルのおかげで、記録と共有を両立できた
  • 障害対応の初動で対面コミュニケーションを取れた
    • 精神的負荷の一番大きなフェーズで負荷を抑えることができた
    • 方針決定までの速さが今までよりも早かった
    • 対応メンバー全員がバッチ周りに詳しくなった
  • 落ち着いたら自席&Slackコミュニケーションに移った
    • ずっと1日中対応しているのではなく、他のタスクにも移行できた
    • 結果、対応に対する時間を削減できた

個人的に学びがあったのは、対応の状況によって 会議室&対面 → 自席&Slack に移行したことで、対応の総コストと精神的負荷を抑えることができたという点です。

ともあれ、「何かあったら会議室」というのもおかしな話なので、臨機応変に活用していきたいと思います。

今回、「障害対応にはフェーズがある」ということと「新しい障害対応の方法」に気づけたのは非常に価値がありました。この経験を踏まえ、今後に活かしたいと思います。

 


 

VOYAGE GROUP では最近Podcastを始めました。 → Ajitofm

社内バー AJITO での語らいを収録したポッドキャストです。技術談義で盛り上がったり、もしかたら今後、障害対応の裏話なども聞けるかもしれません。

Jupyter Notebook でとりあえず Redash へクエリを投げておけばデータソースはなんでも良い状態にする

こんにちはこんにちは!株式会社 fluct で Web 広告配信のお手伝いをしている @jewel_x12 です!

本記事は Redash が便利という内容です。

Redash とは

redash.io

Redash とは Web ブラウザから様々なデータソースに対するクエリを投げて、結果を可視化する OSS になります。 Redash には便利な機能がいくつか機能があるのですが、数点挙げると

  • 様々なデータソースへの対応
  • クエリの定期実行とアラーティング
    • Slack などへの投稿
  • クエリ結果のキャッシュ
  • Google OAuth などいくつかの認証サービスでユーザー管理ができる

あたりです。

弊社では Redash が広く導入されており、エンジニアなどの職種に関わらず利用者がいます。BigQuery のクエリへ Quota をかけられたり、機微な情報のあるテーブルへアクセス制限できるところなどが誰でも気軽に利用してもらえるところかもしれませんね。

個人的にメチャ推しなポイントは様々なデータソースへの対応です。サポートしているデータソースの一覧を見ていただければ分かるのですが、MySQL や AWS の DB 系サービス、BigQuery や ElasticSearch などにも対応しています。Redash をハブとして、散らばりがちなデータソースへ1箇所からアクセスできるようになるのが便利です。

Jupyter Notebook から Redash を使う

さて、自分は広告ログ周りのデータを見ることがあります。解析結果の可視化やレポーティングは Jupyter Notebook を利用しています。Jupyter Notebook はコードのインタラクティブな実行環境であり、Python などのコードをセルという単位で処理したり可視化したりできます。実行結果はいくつかの方法で export 可能であり、グラフなどを共有するのにも役立ちます。私は Jupyter Notebook をベースとした Google Datalab の Docker コンテナを起動して利用しています。Google Datalab を使用しているのは、はじめ BigQuery だけ使用することを考えており BigQuery アクセス用ライブラリなどが最初から使えるので利用していました。*1

実際は各種 ID などを他のデータソースと JOIN したくなるケースが多く、MySQL などのデータソースも利用したくなりました。Jupyter Notebook から MySQL への接続は可能ですが、接続用パスワードの管理があったり、他のデータソースが増えてくると各クライアントの初期化や使い分けが煩雑になりそうだったので、Redash をハブとしてクエリを投げるようにしてみました。とりえあず Redash へクエリを投げることができればデータソースはなんでも良くなります。弊チーム内ではある程度のユースケースはカバーできそうでした。

Redash API Client

Redash にはクエリを実行したりする API があるので、 Jupyter Notebook からは簡単なクライアントを書いて利用しています。

github.com

Jupyter Notebook ではこのクライアントからの結果を pandas.DataFrame へ変換するラッパーをスタートアップスクリプトに書いています。

from redquery import Client

host = 'https://redash.host.example'
myr = Client(host, api_key, mysql_datasource_id)
bqr = Client(host, api_key, bigquery_datasource_id)

def mquery(q):
    return query(myr, q)

def bquery(q):
    return query(bqr, q)

def query(client, q):
    res = client.query(q)
    return (pd.DataFrame(res.rows), res)

api_key は Redash のユーザー画面に API Key というタブがあるのでそちらを利用しましょう。datasource id が admin ユーザー以外には分かりにくいのですが、てきとうなクライアントを作って client.data_sources() とかやるとデータソースとデータソースIDの対応を取得できます。

f:id:jewel12:20170630131939p:plain

クエリエラーも分かります。

f:id:jewel12:20170630132425p:plain

これで Redash とつながっているデータソースに対してクエリを投げられるようになりました。 といってもまだ MySQL や BigQuery でしか試していないので、他のデータソースだとうまく動作しない可能性があります。

それにしても API Key ひとつで異なるデータソースへクエリが投げられるのは、なかなか便利です!

おまけ

Redash を長く運用していると、過去に設定した定期実行クエリがずっと動いているというようなことがあります。 BigQuery で定額料金ではない場合など、クエリ毎に課金が生じるタイプのクエリは定期的に棚卸ししてあげるとコーヒー代くらいは浮くかもしれません。

scheduled_queries = [ q for q in client.all_queries() if q['schedule'] ]
for q in scheduled_queries:
    print("http://redash.host.example/queries/%d\t%d\t%s\t%s\t%s\t%s" % (q['id'], q['data_source_id'], q['name'], q['schedule'], q['created_at'], q['user']['name']))

*1:ちなみに Datalab のサービスを利用せずコンテナを起動して利用しているのは解析結果を GitHub の nbviewer 機能で共有するためです。解析結果を共有したい相手が Google Datalab を動かすための VM インスタンスを立てられる人ばかりではないのと Jupyter Notebook 自体を触る人はそんなに多くないので、実行環境は各自が用意すれば良いという観点から、Github アカウントを作ってもらい共有するほうが楽だと考えました。Google Cloud Source Repositories にそのような機能があると Google アカウントだけでよくなるので嬉しい……

「子供向けブロックプログラミング学習ツール」進化しました!

エンジニアの tatenosystem です。

今回の記事は「私が個人的に作成しているサービス」の紹介です。

 

前々回の2013年09月ブログ  で

 

ビジネスチャンス キタコレ!!!

 

ということで 子供向けプログラム学習ゲーム「たてのブロックサービスを個人的に作成してみました。

開発理由などは 前々回ブログ を見てください。

 

ブロックを配置することでプログラムを作り、キャラクタを動かしてゲームをクリアするゲームです。

 

その後、 文部科学省の「小学校でのプログラミング教育必修化」などの話題があったり、子供向けプログラム教室のリリースを多数見かけたり、子供向けプログラムがビジネス誌の表紙で取り上げられたり、

 

f:id:vg-k-tateno:20170622124515p:plain

 
ここ数年、子供向けプログラミング市場が盛り上がってきてました。

 

しかし「たてのブロック」は全く流行っていない。。。

 

これはもう、サービス名が悪いんじゃないかな。。。

 

そんなわけでサービス名を改名しました。

 

「たてのブロック」改め「コードゲーム」

 

コードゲーム (CODE GAME) - プログラム学習ゲーム

 f:id:vg-k-tateno:20170622130719p:plain


サービス名だけでなく、内容も進化しました。

 

■ 素晴らしい素材画像を見つけたのでキャラ、背景画像の変更

 enchant.js に添付されていた「クマ」画像から、キャラ、背景画像を変更

 

■ プログラム状態を含めて「URL」を生成

「たてのブロック」では URL にマップ情報を保持してましたが、それに加えて作成したユーザーが作成したプログラムも URL に保持しました。


これで URL を送れば、作成したプログラムを他人に見せることができます。

ぐるぐる回るサンプルプログラム

 ■ WordPress から markdown 自作の CMS へ

 

WordPress でサイトを作成してたのですが、度重なるバージョンアップ対応に心が折れたので、簡易な MarkDown 形式の CMS を作成しました。こんな感じで更新しています。

 

f:id:vg-k-tateno:20170622125016p:plain

 

■ 「城」の追加

f:id:vg-k-tateno:20170622130634p:plain

いままでは全ての「宝箱」を取ればクリアでしたが、もし画面内に「城」がある場合は、すべての「宝箱」を取った後に「城」に行くとクリアになりました。

 

 

サービス紹介がてら下記ゲームをクリアしていきましょう


下の画像クリックでゲームがスタートします。

f:id:vg-k-tateno:20170622131343p:plain

 

「中央にあるブロック」を「ドラッグ&ドロップ」で「左のプログラムエリア」に配置します。

f:id:vg-k-tateno:20170622131431p:plain

 

配置したブロックは プログラムエリア外に「ドラッグ&ドロップ」すると消えます。


配置したブロックを「クリック」すると向きや状態が変わります。

f:id:vg-k-tateno:20170622131459g:plain

 

背景が「黄色」、「白」のブロックは向きや状態をクリックで変えることができます。

 

実行ボタン でプログラム動作し「主人公」が動きます。

f:id:vg-k-tateno:20170622131523j:plain

 


「プログラムの作り方」はこのページに書かれています。


使用できる「プログラムブロック」はこのページに書かれています。


紹介のため、今回紹介したゲームの「クリア動画」を作成しました。

 

 

今後も「コードゲーム」は進化していきます!

ゲーム作成機能 もあります。是非「コードゲーム」で遊んでださい。

 

ECナビがAWS導入事例に掲載されました!

こんにちは、VOYAGE GROUP システム本部の @s-tajima です。

先日AWSに移転したECナビが、導入事例の1つとしてAWSのWebサイトに掲載されました。
https://aws.amazon.com/jp/solutions/case-studies/voyage-group/

  • なぜAWSに移転することを決めたのか
  • AWSへの移転を実現するためにどのような取り組みを行ったか
  • AWSに移転することでどのようなメリットを享受できたか

といった内容が記載されています。

AWS移転に関連する取り組みは、先日公開した「インフラチームと開発チームの垣根をなくすためにAWSのCI環境を構築した話」の記事でも紹介しています。

最近のECナビチームはAWS移転以外にも、

  • 動的コンテンツを含むサイト内の全コンテンツをCDN経由での配信に
  • Jenkins 2.0 + Blue Ocean を使ったプロビジョニングのリリースパイプラインを構築
  • PHP 7.1 を使った新しいバッチ基盤を構築
  • Embulk, Redash, Redshiftを用いたデータ分析環境の構築

といった取り組みでシステムの改善を行っています。
これらについてもどこかの機会でご紹介できればと考えています。

最後に、このような改善に興味のある方は是非ご連絡下さい。
ECナビ事業本部 システム基盤エンジニア

こんな環境でアプリケーションの開発をしてみたい方もお待ちしております。
ECナビ事業本部 サービス開発エンジニア

足湯で進捗最高! 熱海の温泉旅館おんやど恵さんで開発合宿してきた!

f:id:chocopie116:20170530114420j:plain

風呂グラミングの実績解除した @chocopie116 です。

熱海の温泉宿に開発合宿に行ってきました。 去年立ち上がったばかりのチームに所属するエンジニアメンバー5人で行きました。 開発合宿興味あるけど準備とか大変そう!自分も風呂グラミング実績解除したい!といった方々のご参考になればと思い書きます。

tl;dr

f:id:chocopie116:20170530191952j:plain

  • オフィスから離れた環境で集中できた
  • 美味しいゴハンと温泉で最高にリフレッシュできた
  • 思ってたより近い(都内から宿までドア・ツー・ドアで1時間半)

スケジュール

f:id:chocopie116:20170531192625j:plain おおまかには以下のようなスケジュールで進めました。

5/29(月)

  • 10:30~11:40 移動(渋谷〜熱海)
  • 11:40~13:00 昼食 & 宿への移動(熱海駅〜宿タクシーで20分)
  • 13:00 宿にチェックイン
  • 13:00~ 18:30 開発タイム
  • 18:30~ 宿の夕食・入浴

5/30(火)

  • 8:00 朝風呂
  • 8:30 宿の朝食
  • 9:30~13:00 開発タイム
  • 13:00~14:00 昼食(外出)
  • 14:00~19:30 開発タイム
  • 19:30~ 宿の夕食・入浴

5/31(水)

  • 8:00 朝風呂
  • 8:30 宿の朝食
  • 9:30~12:00 開発タイム(チェックアウト後も使える)
  • 12:00~13:30 (宿~熱海駅でタクシー)

利用した宿について

f:id:chocopie116:20170531185440j:plain

今回 おんやど恵さんの開発合宿プランを利用させていただきました。

www.onyadomegumi.co.jp

  • ネットワーク快適(無線)
  • 足湯(24h利用可能)
  • 鍵付き会議室の貸出(24h利用可能)
  • 温泉(24h利用可能)
  • ケーブル類(電源タップ等 無料)・サブディスプレイ(27インチ オプション)貸出
  • 施設とてもきれい

オーナーさんがソフトウェアの開発者から旅館経営に転身されたキャリアをお持ちのようで細かな気配りが嬉しかったです。 PCと、PCの充電器しか持っていきませんでしたが、快適な環境で開発をすることができました。

開発合宿について

f:id:chocopie116:20170529120954j:plain

今回合宿でやることは、事前にGitHub issueにまとめておき、当日は簡単な作業のゴールだけ共有した上で作業に着手できました。 各々新規機能開発を進めたり、リファクタリングを進めたり、認証機能のマイクロサービス化の検証をする等もくもくしていました。
いつもより目の前の作業に集中できる分疲れを感じることもありましたが、さっと足湯につかってリフレッシュして作業に戻れるのは個人的にポイント高かったです。

オフィスに足湯ほしい気持ちが高まりました。

まとめ

温泉旅館での開発合宿は控えめにいって最高でした。
合宿で集中して頑張っておいでと快く送り出してくれたチームのメンバーに感謝です。
またオフィスを抜け出して、風呂グラミングで最高な進捗を出していきたいです。

VOYAGE GROUPで利用されているプログラミング言語のトレンドを調べてみた

こんにちは。株式会社ZucksでZucks Ad Networkの開発に携わっている南大津です。

エンジニア採用の募集事項に「業務で使われている言語」がよくありますが、どの言語がどれくらい使われているかは、入社前にはなかなか把握し難い部分ではないでしょうか。
そこで今回は、VOYAGE GROUPで開発に利用されているプログラミング言語のトレンドについて調べてみたので、ご紹介できればと思います。

ソースコード管理について

VOYAGE GROUPでは多くの子会社、サービスが存在していますが、そのほとんどのソースコードはvoyagegroupという1つのGitHub Organizationアカウントで管理されており、現在約400個のリポジトリが作成されています。

私が入社した2009年頃には、ソースコード管理といえばSubversionがメインでした。
その後徐々にGitHubでソースコード管理を行うサービスが増えていったのですが、当初は主に子会社毎にOrganizationアカウントを作成して利用していました。子会社毎にOrganizationアカウントが分かれていると、グループ会社間で知見が広まりづらかったり、アカウント管理を個別に行う必要があったりするため、1つのOrganizationアカウントに統一する流れが起き、今の形に落ち着いています。

今回はこのvoyagegroup Organizationに登録されているソースコードから、VOYAGE GROUPにおけるプログラミング言語の利用状況について調査してみます。*1

最近のトレンドを調べてみる

GitHubにはリポジトリで利用されている言語の割合(バイト数による算出)を表示してくれる便利機能が存在しています。

f:id:smileeeen:20170515194305p:plain

上記のようにリポジトリのステータスバーに表示されているもので、クリックをすると言語ごとの割合が確認できるようになっています。

GitHubでこの情報の算出に使われているライブラリがLinguistという名前で公開されているので、こちらのコマンドラインツールを使ってみます。

github.com

$ git-linguist --help
    Linguist v5.0.10
    Detect language type and determine language breakdown for a given Git repository.

    Usage:
    git-linguist [OPTIONS] stats|breakdown|dump-cache|clear|disable"
    -f, --force                      Force a full rescan
    -c, --commit=COMMIT              Commit to index

git管理されているディレクトリ上で、 git-linguist stats コマンドに特定のコミットハッシュ値を渡すとその時点における言語別容量を返却してくれます。
現在と過去のある時点での言語別容量を比較すれば、最近よく使われている言語の傾向が見えないかなと考え、2017年になってからのvoyagegroup Orgnizationにおける言語別容量の増減を調べてみました。

GitHub APIの呼び出しにはphp-github-apiを利用させていただきました。

github.com

調査に利用したソースコードは下記になります。*2

<?php

require_once 'vendor/autoload.php';

$orgName        = 'voyagegroup';
$diffTargetDate = '2017-01-01T00:00:00Z';
$tmpDir         = '/tmp/techlog';

$client = new Github\Client();
$client->authenticate('【SET ACCESS TOKEN】', null, Github\Client::AUTH_HTTP_TOKEN);

$paginator = new Github\ResultPager($client);
$orgApi    = $client->api('organization');
$repoApi   = $client->api('repo');

$allRepoLangsDiff = [];

foreach ($paginator->fetchAll($orgApi, 'repositories', [$orgName]) as $repo) {
    if (!shouldAggregateRepo($repo)) {
        continue;
    }

    $repoName = $repo['name'];

    $headCommitHash = getLatestCommitHash($repoApi, $orgName, $repoName);
    $pastCommitHash = getLatestCommitHash($repoApi, $orgName, $repoName, ['until' => $diffTargetDate]);

    if ($headCommitHash === $pastCommitHash) {
        continue;
    }

    exec(sprintf(
        'cd %s && git clone --single-branch -n git@github.com:%s/%s.git',
        $tmpDir,
        $orgName,
        $repoName
    ));

    $repoLangsDiff = getRepoLangs($tmpDir, $repoName, $headCommitHash);

    if ($pastCommitHash) {
        $negPastRepoLangs = array_map(function ($v) {
            return -$v;
        }, getRepoLangs($tmpDir, $repoName, $pastCommitHash));

        $repoLangsDiff = sumRepoLangs($repoLangsDiff, $negPastRepoLangs);
    }

    exec(sprintf('rm -r %s/%s', $tmpDir, $repoName));

    $allRepoLangsDiff = sumRepoLangs($allRepoLangsDiff, $repoLangsDiff);
}

function shouldAggregateRepo($repo)
{
    return $repo['size'] > 0
        && !$repo['fork']
        && preg_match('/\A[-.\w]+\z/', $repo['name']) === 1;
}

function getLatestCommitHash($repoApi, $orgName, $repoName, $condition = [])
{
    $commits = $repoApi->commits()->all($orgName, $repoName, $condition);
    return $commits ? $commits[0]['sha'] : '';
}

function getRepoLangs($tmpDir, $repoName, $commitHash)
{
    exec(
        sprintf(
            'cd %s/%s && git-linguist -c %s stats',
            $tmpDir,
            $repoName,
            $commitHash
        ),
        $linguistOutput
    );
    return $linguistOutput ? json_decode($linguistOutput[0], true) : [];
}

function sumRepoLangs($langs, $addLangs)
{
    return array_map(function ($row) {
        return array_sum((array)$row);
    }, array_merge_recursive($langs, $addLangs));
}

// check $allRepoLangsDiff

結果は以下のようになりました。*3

増加している言語
rank 言語 容量変化(MB)
1 Jupyter Notebook 16.2
2 Python 4.0
3 C# 3.5
4 C 2.4
5 C++ 1.3
6 Ruby 1.0
7 Objective-C 0.7
8 CoffeeScript 0.5
9 Go 0.4
10 Scala 0.3
11 ShaderLab 0.3
12 Smarty 0.3
13 TypeScript 0.3
14 Shell 0.3
15 Makefile 0.2
16 HCL 0.2
17 Puppet 0.1

1位のJupyter Notebookに関してはZucks Ad Networkの解析チームで活用しており、純粋なコード量が多いというよりは、Base64エンコードされた画像ファイルもソースコードの容量として含まれている場合があるため、割合が多くなっていると考えられます。
最近ではPythonが人気のようですね。
3位にランクインしたC#はVR室で開発しているUnity製のアプリがメインでした。

減少している言語
rank 言語 容量変化(MB)
1 PHP -8.2
2 HTML -5.3
3 Perl -5.2
4 JavaScript -3.7
5 CSS -3.0
6 Perl6 -0.4
7 Java -0.1

PHPが減っているのはちょっと意外だったので詳しく見てみると、一部のリポジトリで他リポジトリに分割済みのソースコードの削除作業が行われていました。
このリポジトリの増減を除くと、全体で減少していると判定されていた言語の増減は下記のようになりました。

言語 容量変化(MB)
JavaScript 4.0
PHP 1.1
CSS 0.4
Perl6 0.0
HTML -0.6
Perl -0.5
Java -0.1

JavaScriptは増加の2位タイ、PHPは6位というのが実態により近い値のようです。

プログラミング言語別割合の算出

折角なので、GitHub APIのList Languages APIを使ってVOYAGE GROUP全体でのプログラミング言語別割合も集計してみます。

調査に用いたソースコードは下記になります。

<?php

require_once 'vendor/autoload.php';

$orgName = 'voyagegroup';

$client = new Github\Client();
$client->authenticate('【SET ACCESS TOKEN】', null, Github\Client::AUTH_HTTP_TOKEN);

$paginator = new Github\ResultPager($client);
$orgApi    = $client->api('organization');

$totalLangs = [];

foreach ($paginator->fetchAll($orgApi, 'repositories', [$orgName]) as $repository) {
    $repoLangs  = $client->api('repo')->languages($orgName, $repository['name']);
    $totalLangs = array_map(function ($row) {
        return array_sum((array)$row);
    }, array_merge_recursive($totalLangs, $repoLangs));
}

// check $totalLangs

上記を用いて、voyagegroup Orgnizationに存在する全リポジトリの情報を合算してまとめたものが下記になります。*4

rank 言語 容量(MB) 割合(%)
1 PHP 219.9 27.84%
2 HTML 92.1 11.66%
3 Jupyter Notebook 89.2 11.29%
4 Perl 64.7 8.20%
5 JavaScript 64.0 8.10%
6 Python 59.7 7.56%
7 Java 29.4 3.72%
8 CSS 28.6 3.62%
9 Makefile 25.9 3.28%
10 Objective-C 23.3 2.94%
11 Ruby 18.1 2.29%
12 C 16.6 2.10%
13 C++ 16.1 2.03%
14 Smarty 6.7 0.85%
15 ActionScript 6.7 0.85%
16 C# 5.6 0.71%
17 Scala 3.5 0.44%
18 Tcl 2.5 0.31%
19 Perl6 2.3 0.29%
20 Shell 2.0 0.26%
21 Swift 1.9 0.24%
22 Go 1.7 0.22%
23 TypeScript 1.3 0.17%
24 Erlang 0.9 0.12%
25 R 0.8 0.10%
26 Roff 0.8 0.10%
27 CoffeeScript 0.7 0.09%
28 GLSL 0.7 0.09%
29 PLSQL 0.7 0.09%
30 Objective-C++ 0.5 0.07%
31 Kotlin 0.5 0.07%
32 ApacheConf 0.3 0.04%
33 Scheme 0.3 0.04%
34 Protocol Buffer 0.3 0.04%
35 Puppet 0.3 0.03%
36 HCL 0.2 0.03%
37 XS 0.2 0.02%
38 XSLT 0.2 0.02%
39 Groovy 0.1 0.02%
40 Vue 0.1 0.01%

色々な言語が使われていますが、結果としてはPHPが断トツの割合を占めていました。
調査前、私もPHPが20%くらいで一番多いかなと想像していたのですが、予想を上回る27%超えとなりました。
10年以上続いている弊社のメディアECナビがメインでPHPを利用しているなど、PHPを利用しているサービスが多いためだと考えられます。

3位のJupyter Notebookの容量が大きくなりがちなのは前述の通りです。

その他ではPerl、JavaScript、Python、Javaといった辺りがVOYAGE GROUPでは人気があるようです。最近のトレンドから考えるとそろそろPythonがPerlを抜き去りそうですね。
個人的にはMakefileが3%を超えてトップ10入りしているのも、VOYAGE GROUPらしいのかなと感じるところでした。(参考:プロビジョニングツールはMakeで決まりだろ // Speaker Deck

おわりに

最近のトレンドに関しては差分確認期間中に削除されているコードも存在するため、正確には分かりづらい部分がありましたが、少しはVOYAGE GROUPで利用されているプログラミング言語の実態を感じていただけたでしょうか。また1年後には状況が大きく変化しているかもしれません。

皆さんの周りではどういった言語が使われているでしょうか。
この言語をVOYAGE GROUPで広めていきたい!といった想いの方がいらっしゃいましたら是非採用エントリーをお待ちしています。 voyagegroup.com

*1:一部の古くからあるサービスなど、現在でもSubversionを利用しているものや、子会社ごとのGitHub Organizationアカウントで管理されているものもわずかに存在しますが、今回は調査の対象外とします

*2:GitHub APIとgit-linguistコマンドでは、言語判定が若干異なるケースがあるようだったので、直近の言語別容量もgit-linguistを利用して取得しています。

*3:容量変化が±0.1MB未満のものは表から除外しています

*4:容量が0.1MB未満のものは表から除外しています。サードパーティ製のソースコードは一般的なパスにあれば除外されているようですが、含まれているものもあるかもしれません