LIVESENSE made*

リブセンスのエンジニアやデザイナーの活動や注目していることをまとめたブログです。

MENU

9つのWebサイトモニタリングサービスの使用感まとめ

  • はじめに
  • モニタリングサービスまとめ
    • No.1 Site24x7
    • No.2 StatusCake
    • No.3 Pingdom
    • No.4 UPTRENDS
    • No.5 GTMetrix
    • No.6 DareBoost
    • No.7 NodePing
    • No.8 Monitoring Plus
    • No.9 UptimeRobot
  • まとめ
  • おわりに

はじめに

今年4月に中途で入社したインフラストラクチャーグループ所属の内河です。 最近、ジョブセンスのインフラ担当になりました。 オンプレのサーバを触りつつAnsibleのPlaybookを書いたり、AWSのリソース設定をTerraform化しています。

現在、リブセンスではサーバの監視・外形監視にはMackerelを、WebサイトのモニタリングにはNewRelicやDatadogを利用していることが多いです。 しかし、こういったサービスの移り変わりは早く、新しいサービスが出ていたり、既存のサービスも使い勝手が変わっているかもしれません。 今回の記事は、9つのモニタリングサービスについて以下の要件を満たしているか、実際に触ってみた感想や費用について纏めてみました。

  • UIはグラフィカルで直感的か
  • 以下の点をモニタリング出来るか
     1. レスポンスタイムが分かるか
     2. アップタイムが分かるか
     3. DOMContentLoadedやLoad時間が分かるとベター

※ 有名なMackerelやNewRelicなどは除いております。ご了承ください。
※ 記載した費用は2017/08/10日現在の割引を適用していない費用に基いています。

それでは実際に見てみましょう。

続きを読む

Livesense式 開発合宿マニュアル part2

f:id:taise:20170708180350j:plain

就活会議ユニットのエンジニアをしている大政です。
最近、データ分析基盤を開発する部署から異動になりました。

開発合宿、やっていますか?
半年前に、Livesense式 開発合宿マニュアル part1という記事を書きましたが、今回はその続きです。

開発合宿を有意義なものとするために、いろいろな試行錯誤がありました。
3年間やってきた中で得られたノウハウを共有できればと思います。

開発合宿アンチパターン

  • 会場に到着してから何を作るか考え始める
  • 持ち物の準備不足
  • 旅行として満喫してしまう

会場に到着してから何を作るか考え始める

各自でもくもく取り組むタイプの開発合宿で発生しやすいです。
いいものが考えつかないまま、あれこれ探している間に何時間も過ぎてしまい、気づいたときにはタイムアップ、という流れです。

開発合宿は、会場への移動や食事などで、自由に開発できる時間は意外と限られています。
その貴重な時間は、全て開発につぎ込まなければ、作りたいものを完成させられずに終わってしまいます。

持ち物の準備不足

宿泊施設によっては、電源タップがないため交代で充電しないといけなかったり、Wi-Fiありとなっていても、回線が弱くてみんなでつなぐとまともに使えないケースもあります。
開発に集中するためにも、環境を整えるための準備が大事です。

旅行として満喫してしまう

開発合宿は、温泉地や海辺などで行うことが多く、誘惑が多いです。
ともすると、1日中遊んでしまって開発が疎かになってしまう、ということもありがちです。

気分転換は必要ですが、開発合宿で遊びすぎてしまうと後ろめたさはあるし、開発時間がもったいないです。
開発時間と遊ぶ時間は、ある程度参加者全員で揃えておいたほうが無難です。

有意義な合宿にするために

合宿のしおりをつくる

リブセンスの開発合宿では、集合場所や開催場所、移動ルートや費用などをざっくりまとめた合宿のしおりを作っています。
参加者で事前に集まってしおりの読み合わせをすると、合宿に行く機運が高まります。しおりを作るタイミングで、開発時間と遊ぶ時間をある程度決めておくと、気持ちよく過ごせるでしょう。

また、後述するさまざまな点で、しおりの読み合わせは役に立ちます。

f:id:taise:20170802143330p:plain

持ち物リストを作る

前回ご紹介した開発合宿施設は、至れりつくせりで困ることはほとんど無いと思います。とはいえ、事前に持ち物リストを作ってちゃんとチェックしておくことに越したことはありません。

例えば見過ごしがちな持ち物として、ヘッドホンがあります。
会議室を借り切って開発をする場合、他の参加者の会話やBGMが気になる方もいるでしょう。 その際にヘッドホンがとても役立ちます。

MacのACアダプタは、比較的短いため、あまり自由に動けなかったり、延長コードの形状によっては、Macのアダプタがあまりつなげられない場合もあります。
その際に、Macを購入するとついてくる延長コードがあると大変便利です。

リブセンスでは以下のような持ち物リストを使っています。

  • PC*
  • ACアダプタ*
  • お泊りセット*
  • 携帯の充電ケーブル*
  • 電源アダプタ 延長コード (Mac)
  • ヘッドホン
  • お酒 🍶

*required

この他、ボードゲームを持っていったりするメンバーもいます。 合宿のしおりに、個人の持ち物と、全体で分担する持ち物を書いておくとスムーズです。

お酒の持ち込みは、宿泊施設によっては禁止されていたり、持ち込み料が必要なケースがあります。 事前にご確認ください。

出発前に何をやるか決める

会場に到着する前に、何をやるか決めてもらうことが大事です。
しおりの読み合わせをした時に、参加者に一人ひとりやることを聞いていき、 決まっていない人はその場で一緒に考えつつ、必ず決めてもらうようにしています。

当日までに作るものが変わっていても構わなくて、考える切っ掛けを事前に作ることが大事だと思っています。

中間発表/成果発表

合宿中に発表の場を作るのはとても重要です。
多くの人は締切がないと頑張れません。

初めてやった開発合宿は、各自がそれぞれだらだら開発してなんとなく終わってしまいました。 日々の進捗は中間発表で、最後は成果発表で自分のやったことを他の参加者に説明すると決まっていると、 何らかの形で動くもの・成果が見えるものを作りたくなります。

継続するために

これまでのノウハウを活かして開発合宿がうまく行ったら、ぜひ2回、3回と続けたいものです。 最後は継続のための工夫をお伝えしたいと思います。

  • 定期開催の流れを作る
  • 運営を複数人で分担する
  • 個別に勧誘する

定期開催の流れを作る

「毎年何月に開発合宿をやる」と決めておくと、それに合わせて開催の準備をすることができて、自然と定期開催することが来ます。
リブセンスでは大体6月と11月に開催しています。宿の繁忙期を避けるためです。

運営を複数人で分担する

最初期は1人で運営するのもやむを得ないかもしれませんが、日程調整から宿の予約など、やることは結構多いため大変です。 自分1人でやりきろうとすると、自分の気持ちが切れたときに、開発合宿も開催されなくなってしまいます。

参加メンバーに相談して一緒に準備してもらうと良いでしょう。
運営メンバーが複数になると、負担も軽くなり、他のメンバーからの開催のプレッシャーもかかるため、継続しやすくなります。

勧誘する

毎回参加してくれるメンバーも、子供が生まれるなどのライフステージや環境の変化で参加できなくなるということがあります。初期メンバーだけでは、どんどん参加者は減ってしまいます。 新しいメンバーに参加してもらい、刺激が得られたり、マンネリ化を防ぎましょう。

ただし、新しく参加するのはなかなかハードルが高いのも事実です。 開催の告知をするだけでは、「参加してもいいけどどうしようかな」と悩む方も多いようです。

直接声をかけたり、仲の良い同期同士で誘い合ってもらうことで、参加のハードルが下がります。勧誘をして、合宿仲間を増やしましょう。
開発合宿を楽しんでくださった方は、繰り返し参加して頂けます。

おわりに

part2は以上です。
ぜひこれらのノウハウを活用して、楽しい開発合宿を開催して頂けたら幸いです。

就活会議トップページをリニューアルしたときのCSS設計のお話

16卒で入社したエンジニアの田口です。 就活会議というメディアで、主にフロントエンド開発を担当しています。5月にトップページをフルリニューアルしましたので、その時のCSS設計についてお話しいたします。

就活会議のフロントエンド開発では、FLOCSSを採用しています。
1カラムのレイアウトの場合、2,3カラムの場合と比較して

  • どのパーツをLayoutにすべきか
  • どこまで細かくProjectとしてきり出すべきか

が曖昧になりやすく、開発者同士の議論が増え、コードの修正も多くなりました。

そこでパーツ単位の実例を、「ファーストビュー」と「企業口コミ」の2つを用いて、トップページのCSS設計について解説していきます。

トップページのファーストビュー

f:id:livesense-made:20170629122439p:plain

こちらのトップページのファーストビューでは、背景に動画を流し、その上にヘッダーパーツ、真ん中にメッセージパーツ、その下にテキストパーツがある構成になっています。このような場合、どのような設計をするのが適切でしょうか?

Layoutのクラスを作るべきか、Projectの単位はどうするのか、など悩みどころは多いかもしれません。 今回は以下のクラス設計で実装しました。Firebug等で実際に確認していただければと思います。

f:id:livesense-made:20170725151127p:plain

ポイントとしては、Layoutの責務とProjectの責務を明確に分離したことです。 l-top-visualというファイルにファーストビューのLayoutに関するクラスをまとめています。

_top-visual.scss
//------------------------------
//トップページのビジュアルのスタイル
//------------------------------

.l-top-visual {}
.l-top-visual__video {} 
.l-top-visual__filter {}
.l-top-visual__header {}
.l-top-visual__message {}
.l-top-visual__appeal {}

今回はabsoluteで、ヘッダーや中心のメッセージパーツなどの位置を指定しているため、場所を指定する要素はLayoutに書き、その中にProjectファイルでパーツのクラスを入れました。 他にもposition指定は1つのファイルにまとめておきたかったいう理由もあります。

一般的にLayoutのクラスはl-header, l-sidebarのように汎用的に使うことを想定されています。 しかし、今回はProjectファイルにLayoutの要素を持たせるのをやめて、Layoutの責務とパーツ単位の責務を明確に分離する方針をとりました。

企業口コミのパーツ

f:id:livesense-made:20170629123311p:plain

続いてこちらの企業口コミのパーツです。1つのProjectファイルで設計した場合、以下のようになるかと思います。

_top-word-mouths.scss

//-----------------------------------
//トップページの口コミ、口コミパネルのスタイル
//-----------------------------------

.p-top-word-mouths {}
.p-top-word-mouths__title {}
.p-top-word-mouths__desc {}
.p-top-word-mouths__content {}
.p-top-word-mouths__content-inner {}
.p-top-word-mouths__panel {}
.p-top-word-mouths__panel__img {}
.p-top-word-mouths__panel__img-mask {}
.p-top-word-mouths__panel__img-text {}
.p-top-word-mouths__panel__content {}
.p-top-word-mouths__panel__content-company {}
.p-top-word-mouths__panel__content-star {}
.p-top-word-mouths__panel__content-star-text {}
.p-top-word-mouths__panel__content-category {}
.p-top-word-mouths__panel__content-text {}
.p-top-word-mouths__panel__btn-area {}
.p-top-word-mouths__panel__btn {}
.p-top-word-mouths__panel__img {}

各クラスの要素を書いていないためわかりにくいですが、1ファイルでコードが200行を超えてしまい、かつElementのElementが存在してしまいます。 最初はこのように設計していたのですが、最終的には

  • .p-top-word-mouths
  • .p-top-word-mouth-panel

の2つのプロジェクトファイルに分けて作成しました。

f:id:livesense-made:20170706180343p:plain

各ファイルのクラスは以下のようになっています。

_top-word-mouths.scss
//------------------------------
//トップページの口コミのスタイル
//------------------------------

.p-top-word-mouths {}
.p-top-word-mouths__title {}
.p-top-word-mouths__desc {}
.p-top-word-mouths__content {}
.p-top-word-mouths__content-inner {}
_top-word-mouth-panel.scss
//-----------------------------------
//トップページの口コミのパネルのスタイル
//-----------------------------------

.p-top-word-mouth-panel {}
.p-top-word-mouth-panel__img {}
.p-top-word-mouth-panel__img-mask {}
.p-top-word-mouth-panel__img-text {}
.p-top-word-mouth-panel__content {}
.p-top-word-mouth-panel__content-company {}
.p-top-word-mouth-panel__content-star {}
.p-top-word-mouth-panel__content-star-text {}
.p-top-word-mouth-panel__content-category {}
.p-top-word-mouth-panel__content-text {}
.p-top-word-mouth-panel__btn-area {}
.p-top-word-mouth-panel__btn {}

この粒度であれば、1つのProjectファイルにまとめても良いかもしれませんが、 就活会議では以下をHTML・CSSのコーディング規約としてルール化しています。

  • ElementのElementは作らない
  • ファイル数が増えるのを許容して細かくProjectファイルを切り出す

この2点により

  • クラス名が長くなることを避けられる
  • 各ファイルの行数を少なくすることにより、ファイルの見通しが良くなる
  • ProjectをComponentにする際の変更が容易になる
  • HTML構造が変わった際に、クラス名を変更することを避けられる
  • Viewを見た際に、開発者がどのファイルを見ればいいかすぐにわかる

というメリットが得られます。 そのため、就活会議ではElementのElementを許可せず、Projectファイルを小さく切リ出す方針をとりました。

簡単ではありますが、トップページの実例を用いて就活会議のCSS設計についてご紹介しました。CSS設計の参考になれば幸いです。

Railsでの秘匿情報の取り扱いを運用しやすくするgemを作った話

f:id:livesense-made:20170720182249j:plainみなさんこんにちは。ジョブセンスでエンジニアをしている小沼です。初めまして。 16新卒で入社して現在2年目になります。 去年はSQLで円グラフを書いたりしていました。

さて、本題に入ります。先日新規でRailsリポジトリを立ち上げたのですが、その時に秘匿情報の取り扱いについて考えたことがあったので紹介いたします。

Rails5.1から導入されたEncrypted Secretsについて

Rails5.1から標準でEncryptedSecretsという機能を使うことができるようになりました。

参考: Rails 5.1: Loving JavaScript, System Tests, Encrypted Secrets, and more | Riding Rails

使い方はざっくりと以下の通りです。

# 鍵とsecretsを準備
# 鍵ファイルは自動で.gitignoreに追記される
$ bundle exec rails secrets:setup

# 編集
$ bundle exec rails secrets:edit

上記の操作で秘匿情報をセキュアにgit管理することができます。 暗号化された情報はconfig/secrets.yml.encに保存されていて、アプリケーションの初期化に際してconfig/secrets.ymlの内容とmergeされます。

実際にアプリケーション上で取り扱う際は、
config/application.rbまたはconfig/environments/*.rbconfig.read_encrypted_secrets = trueとした上、Rails.application.secrets.hogehogeで参照することができます。

正直なところ、かゆいところに手が届かない

新規で作成したリポジトリではRails5.1を使っていたので、EncryptedSecretsを使うことができる環境でした。 しかしながら実際の運用を始めてみると、EncryptedSecretsは少々使いにくいなと思うことがでてきました。

そのように感じた主な理由は以下3点です。

  • 暗号化された情報は一行で記述されるため、コンフリクトが起きやすい
    • 当然、変更のたびにファイル全体が変更されるため、どの情報がいつ変更されたのか確認できない
  • ファイル全体が暗号化されるため、そもそもなんの情報が暗号化されているのかすらわからない
  • せめてansible-vault showみたいな閲覧するだけのコマンドが欲しい

なのでぼくの欲求を満たしてくれるGemを作った

実現したいことは以下の通りです。

  • 暗号化するのはYAMLの末端(葉)で、かつkey: valuevalueのみ
    • (それによってセキュアさが落ちることは許容する)
  • 暗号化したあともYAMLの構造は守る
  • 複合化した情報を手軽に参照できるコマンドを提供する

そしてできたのがleml(Leaf Encrypt YAML)です。

lemlの概要

インストールと使い方

lemlはRailsのプラグインとして実装されていて、秘匿情報はrakeタスクによって閲覧、編集を可能にしています。 実際のRailsプロジェクトはGemfile/Gemfile.lockによってgemを管理することが多いと思います。通常のgemをインストール手順と同じく、

# Gemfile
gem 'leml'

とした上で、$ bundle install

初期化

その後、初期化を行います。

$ bundle exec rake leml:init
Complete!
create  config/leml.key
create  config/leml.yml

Caution Don't forget add key file in gitignore

※ 自動的に鍵ファイルは.gitignoreに追加されません(今後機能として追加していく予定です)
※ デフォルトでYAMLのシンタックスハイライトが効いて欲しかったので本家のファイル名にある.encサフィックスは削除させてもらいました

編集/閲覧

暗号化されたファイルの編集、閲覧は以下のように行います。

$ EDITOR=vim bundle exec rake leml:edit

これでvimが立ち上がり秘匿情報の編集ができるようになります。環境変数'EDITOR'を利用するのでお好きなエディタをセットしてください。 保存して終了すると、内容を暗号化した上でconfig/leml.ymlが更新されます。編集する必要はなく、内容を確認できればいい場合は以下のコマンドで標準出力に出力することも可能です。

$ bundle exec rake leml:show

実際に使ってみると以下のようになります。
元のYAML

---
development:
  gem:
    leml:
      author: onunu
      github: https://github.com/onunu
  favorite_precure: twinkle

上記の内容を暗号化すると、

$ cat config/leml.yml
---
development:
  gem:
    leml:
      author: aFR1RWUyT0RoVTJzSlgrZ0ptVmlqdz09LS0vL2hzZXVLMzZtTFJ5dk1ZSzdqQ2lRPT0=--bced3fd4f521287b819edb677460e2518bcefb8b
      github: ZW9PcTBYMy8xakZQUXhqVmhWNlNxNXBKMmM3Z3FLTDZKVEdoRmFzUnB4Z2JScTNKMlo1VktiK0NZS01JVlpLWC0tc2hHTTlrTytOYXpJckxIMmhhNWV5QT09--5340c65706b5619afcc81318dca47c033aecf65f
  favorite_precure: T21uN2R0NjhsNjdHOHgzY1d6WHp5RDRibnNYVHBOY2l4TC9rcmc1UGZ5OD0tLXllQnQrTXk0Q3lVdmtTdzAzQVprVXc9PQ==--e2568a8cfa84055f367dce531f5e287ac5182033

階層構造があっても問題ありません。何が暗号化されているのか一目瞭然! 実際のアプリケーションから参照する時は、通常のsecretsと同様に扱うことができます。

$ bundle exec rails c
Running via Spring preloader in process 68212
Loading development environment (Rails 5.1.2)
irb(main):001:0> Rails.application.secrets.favorite_precure
=> "twinkle"

なにをしているのか

Railtieについて

lemlはRailsの初期化プロセスに相乗りする形でsecretsをmergeしていますが、これはrailtieを使うことで比較的簡単に実装することができます。 lemlでは以下のようにしてRailsの初期化プロセスを拡張しました。

# leml/lib/leml/railtie.rb
module Leml
  class Railtie < Rails::Engine
    initializer 'Decrypt Leml file' do
      require 'leml/core'
      Leml::Core.new.merge_secrets
    end
  end
end

RailtieはRails公式のプラグイン機構です。Railtieに基づいて各コンポーネントを組み合わせることで、Railsの様々な処理を手軽に拡張することができます。自作のgem(今回でいうところのLemlモジュール内)でRails::Engineクラスを継承したRailtieクラスを定義することで、Railsが処理を行う際に相乗りさせてもらえます。

参考: Rails::Railtie

今回は初期化プロセスを拡張したいので、内部でinitializerメソッドを定義しました。これにより、Railsが実行する初期化と同時に、initializerメソッド内で記述した処理をRailsが行ってくれます。

各タスクについて

lemlでは各操作をrakeタスクで提供しています。 Rails pluginではleml(gem名)/lib/tasks配下にrakeファイルを設置することで、Railsプロジェクトのタスクとして読み取ってもらえるだけでなく、タスクの実行時にはRailsの初期化プロセスが行われた後でタスクを実行してくれます。

lemlのrakeファイルは以下のようになっています。

# leml/lib/tasks/leml_tasks.rake
require 'leml/core'

namespace :leml do
  desc 'initialize secrets yaml'
  task :init => :environment do
    Leml::Core.setup
  end

  desc 'edit encrypted yaml'
  task :edit => :environment do
    Leml::Core.new.edit
  end

  desc 'show encrypted yaml'
  task :show => :environment do
    Leml::Core.new.show
  end
end

終わりに

いかがでしたか? 自分で書いたファイル数は4つくらいでしたし、それぞれ基本的なことしかしていません。 それでも自分のやりたかったことはある程度実現できました。Railsの懐の深さに驚きです。

また本家のEncryptedSecretsの実装、Railtieの仕組みなどを理解するのにソースコードを読みましたが大変勉強になりました。やはり一次資料はソースコードですね。

lemlはオープンソースで提供しているので、みなさん使ってみてくださいね! まだまだ至らぬ所はありますが、メンテ頑張っていきたいと思います。ご要望やバグ報告、その他ご指摘などはissueを立ち上げていただけると幸いです。

ご注意

lemlはYAMLファイル中のkey: valueのうちvalueだけを暗号化します。当然、keyは平文のまま残るため、keyからvalueの値を推測されてしまう危険性をもっています。 そのリスクを許容できない場合はRails標準のEncryptedSecretsを利用するか、あるいは併用するのがよいでしょう。 ご利用の際にはご注意ください。

転職クチコミサービスでのプロダクトチーム文化と取り組み

背景

転職クチコミサービスの転職会議を開発するプロダクトチームは2014年頃には6名ほどの小さな組織でした。

2017年現在は30名強と、徐々にメンバーを増やしながら成長してきました。

今回はこのチームで作り上げてきた文化の話をしたいと思います。

Team Geekとの出会い

僕たちが成長する上で強く影響を受けた書籍がTeam Geekです。

HRT(謙虚・尊敬・信頼)などで有名な名著ですが、チーム文化についても重要な項目として語られています。

この文化というのは非常に捉えづらいものではありますが、文化を意識してチームを作る事が非常に大切だったなと感じています。

Spotify engineering cultureとの出会い

文化について意識的に作り上げる段階において、強く影響を受けたのがSpotifyの資料です。

前後編合わせて30分程度の短い動画ながら、Agileの精神、Leanな開発、上手な「失敗」の仕方など、非常に濃い内容が含まれています。

2014年の資料であるにもかかわらず、今でも共感できる内容がたくさん含まれています。

皆が同じ目標を向き、自律的に動く組織文化

Spotifyの資料の中で特に影響を受けたのが「高いAlignmentかつ高いAutonomyな組織」のモデルです。

少々馴染みの薄い言葉なので、それぞれ意味を訳してみます。

Alignmentは、「整列」や「同調」「一致性」「団結」など、一方向へ向かう様子を表しています。

Autonomyは、「自治」・「自律」という意味になります。

つまり「同じ方向を向いた状態」でかつ「自律的である」という事になります。

この2つの概念は、それぞれ相反するような概念に思えるかもしれません。

しかしSpotifyの資料においては、むしろ「高い一致性こそが高い自律を可能にする」とも語られ、どちらも高い状態であることを理想であるとしています。

f:id:livesense-made:20170705234101p:plain

もう少し深掘りすると、理想像はこのようなことと言えます。

  • 明確なミッションを持ち、メンバーとリーダー全員が、同じ方向を向いて同じ目標に向かって進む
  • メンバーは「どう解決するか?どれが最適か?」の部分を考えて実行する。
  • リーダーは「何が課題か?解決のために何が必要か?」に責務を持つ

Team Geekでもミッション・ステートメントの重要さや、サーバントリーダーなど類似する考え方があり、これらの重要さが語られています。

この「明確なミッションを高いレベルで共有し、高い一致性を持ち高い自治性があるチーム」という理想像は、転職会議のチーム文化へ強く影響を与えてくれました。

高い一致性と自律性を持ったチームで何が出来るか?

それでは高い一致性と自律があるチームは何が良くて、何が出来るのでしょうか?

ここからは僕たちが理想像のチームだからこそ出来たと感じていることを紹介していきます。

とりあえずやってみる → 上手く行ったら残す/駄目ならすぐ捨てる

新しい仕組みやツールへのトライアル・施策は様々な懸念があったり、障壁が高いなどがあり、どうしても腰が重くなりがちです。

転職会議では「とりあえずやってみよう」を合言葉に、フットワークを軽くアクションを起こす文化を推奨しています。 まず小さくやってみる→運用してみる→上手く行ったら残す / 駄目なら修正するか撤退する、という流れです。

Spotifyの資料では、Part2の「Waste-repellent Culture」という項目で類似の事が紹介されています。 また、Lean Startupの考えともほとんど同じです。

当然、各々が何も考えず無作為にいろんなものを取り入れてしまえば混沌としてしまう可能性もありますが、各自が責務と自由のバランスの上で行えているので今のところ適切にワークしています。

標準化(Standalization) より 異花受粉(Cross-pollination)

リブセンスではPHPやRuby on Rails、Go、Reactなどがよく使われています。

これらはすべて誰かが決めたわけではなく、自然発生的に広まっていきました。

Spotifyの資料においては異花受粉(Cross-pollination)という呼び方で、この徐々に良いツールがチームからチームへ伝播してデファクトスタンダードとして広まる現象を説明しています。併せて、一貫性と柔軟性が保たれる効果をもたらされる利点も説明されています。

新しい言語やツール、ライブラリを一つのチームが取り入れて、それが良いものであれば隣のチーム・リポジトリにも使われるというフローは、開発にはよくあるごく自然な現象です。

しかし、その現象に対して「足並みをそろえて標準化するより、より良いものが自然に伝播していく文化には利点がある」ということをしっかり認識することで、「とりあえずやってみる」の精神をより加速させて来ることが出来ました。

今日まで、良い温度感で技術の新陳代謝を進めることが出来ていると感じています。

「とりあえずやってみる」の部分でも懸念として上がりましたが、こう聞いてしまうと「いろんなライブラリが入って、学習コストが高くなってしまうのでは?」と感じる方もいるかもしれません。

こちらも同様で、各自が正しく目的を捉えた上で適切な技術選定を心がけているため、極端に突飛な選定はされず、各自の責任の持てる範囲でのチャレンジがなされています。

Internal Open-Source Model

Spotifyの資料ではInternal Open-source Modelというのが紹介されており、転職会議でもこの考え方を取り入れました。

これはチームで開発されるシステムを全て内部的なオープンソースと同じように扱い、特定のチームが特定のシステムだけ触るのではなく、必要になったチームがPull Requestをするというやり方です。

この方法はPayPalのInnerSourceも近いかもしれません。

転職会議は現在クチコミ関連の他にも・求人・会員情報・ログイン認証・企業向け管理画面など、大小幾つかのシステムが独立的に動いています。

これらのシステムに対し、専属のチームを設けるのではなくそれぞれのチームが自分たちのミッション・施策に応じて、各チームが必要なシステムに必要なだけPull Requestをしてリリースして作業を進めています。

一つのシステムに対して必ず一つのチームが改修する体制にしている場合、自分たちの施策が他のチームの優先度で左右されてしまったりということがありがちです。

Internal Open-Source Modelを取り入れることによって、各チームが他のチームに依存せずプロジェクトを進めることが出来ています。

リポジトリオーナー

通常のオープンソースにコアなメンテナが存在するのに倣って、各リポジトリに複数人のオーナーとサブオーナーを設けています。 *1 これはいくつかのリポジトリで試験的に行ってみて、うまくいきそうだったので現在展開しています。

オーナー・サブオーナーはOSSのメンテナと同じようにコードレビューを行い、リポジトリの品質や一貫性を担保することが主な責務で、その代わりにリポジトリのライブラリ選定やコーディング規約などもおまかせしています(先に説明したCross-pollinationによる伝播がチーム内でも適度に行われる事も狙っています)。

基本的にはそのリポジトリを頻繁に触るチームのメンバーや、そのシステムに詳しいメンバーから選出しています。システムを触らなくなってきたり、オーナー業務が偏ってきた場合には適切に交代や追加をしていく予定です。

品質の保持や一定の自由度が出来た上での副次的な効果として、コードレビューが一部のメンバーへ極度に偏ったり、逆にレビュアーが多すぎて緊張感の無い薄いレビューになってしまう問題が緩和出来る効果がありました。

また若手メンバーにもサブオーナーになってもらい責務を持った視点でレビューをしてもらうことで、育成の機会になるという部分も見られそうだと感じています。

「やってあげる」よりも「出来るようにする」(Self-serve Model)

転職会議がAWS化した時期を境に、SRE(Site Reliability Engineering)チームが設立されました。 *2

SREチームはサイトのパフォーマンス向上やセキュリティ向上、安定的な運用を目指しているチームです。

まだまだAWSに移行したばかりで、ノウハウが足りない、メンバーの学習が追いつかないなど、様々課題もあります。

新しいシステムの作成などAWSに触る部分が出てきた場合、慣れているSREチームのメンバーが作業をしてしまう方が素早く出来るのですが、どうしても作業が集中してボトルネックになってしまいがちです。

そのためSREチームが直接作業するのは極力減らし、どんどんメンバーが各自で「出来るようになる」という土壌を作ることを心がけています。

フロントエンドにおいても類似です。フロントエンドが得意なメンバーが作業を請け負うのではなく、できるだけ触ったことが無いメンバーをアサインしたり、勉強会を執り行ったりして「出来るようにする」ということを意識しています。

デザイナーとフロントエンドエンジニアのやり取りにおいても、CSSやテンプレート、JSXなどを全部フロントエンドエンジニアがやってしまうとボトルネックになってしまう事があるため、ある程度からはデザイナーだけでもどんどん作業が出来るようにしています。

どちらもInternal Open-Source Modelと同様、各自に信頼を置いてやれる領域を可能な限りで広げ、なるべく他のチームやメンバーがボトルネックになるのを避けるような取り組みです。

部分的なリモート勤務

リブセンスには今のところリモートワークなどの制度はありませんが、転職会議チームでは会社の規則に反せず、チームで適切に運用できる範囲でのリモート勤務を取り入れています。

導入にあたっては、オフィス出社を前提とした上で上手くリモートの自由度を取り入れているQuipperさんの記事を参考にさせていただきました

基本的にはこのようなルールで進めています。

  • 基本的にはオフィスに出社するのが前提。対面の会話は大事にする
    • 在宅勤務をするときはチャットでコメントする。
    • 用事などリモート関係なく出勤時間がずれる場合もチャットでコメント
  • タイムシフトのためのリモートではないので、基本的に作業時間はずらさない
    • だいたい11:00〜18:00でみんなが働いているので、そのぐらいを目安とする
  • 体調不良を理由にしたリモートワークはナシ
    • 低いパフォーマンスで仕事せず、しっかり休んで回復させる

朝や午後に数時間利用したり週に1度丸々リモートにするなど、利用の仕方はメンバーによって様々です。

数ヶ月やってみて今のところ混乱や問題は無く、快適に運用できています。これもメンバーが高い一致性と自律性を持って仕事に取り組めている文化があってこそ上手く行ったことではないかなと感じています。

まとめ

ここまで転職会議プロダクトチームの文化を一部ですが紹介してきました。 今回のお話で興味を持った方は是非Team GeekやSpotify engineering cultureをじっくりと見ていただければなと思います。

転職会議は今後も成長させたいと感じていますし、文化もどんどん強くしていきたいと感じています。

様々変わる部分も今後出てくると思いますが、ミッションに対して高いレベルで一致をしつつ自律した組織を理想像とする志はいつまでも保持していきたいなと感じています。

転職会議では僕たちと文化を育ててくれるメンバーを募集しています!

http://recruit.livesense.co.jp/

*1:なんていう記事を書いている間にgithubにcode ownersという機能が実装されてました。

*2: 転職会議のAWS化の苦労話などは、また別なタイミングで出来たらなと思います