Money Forward Developers Blog

株式会社マネーフォワード公式開発者向けブログです。技術や開発手法、イベント登壇などを発信します。サービスに関するご質問は、各サービス窓口までご連絡ください。

20230215130734

マネーフォワードエンジニアのアウトプットを可視化してみた

こんにちは。 マネーフォワード福岡拠点でインターンをしています長島です。 普段は『マネーフォワードクラウド経費』のサーバーサイドの開発を担当しています。

 

概要

最近マネーフォワード社内で、エンジニアの日々の「開発の調子」や「アウトプット量」を可視化してみたいという話がありました。 そこで、ちゃんとしたダッシュボードなどを作る前に、ひとまずデータの中身を覗いてみようという事でちょっとやってみました。

 

さてどうやる

エンジニアの開発の調子をどう測るという話ですが、やはりまず思いつくのはGitのログを見る事かなと。

幸いGitHubはAPI (GitHub Developer Guide)が非常に充実しており、

  • コミット履歴
  • プルリク履歴
  • デプロイ履歴

などをリポジトリ単位で簡単に取得できるようになっています。

上記のいずれの項目もエンジニアの日々の開発の調子を測る上で重要な指標になりそうですが、最終的に各コミットの編集内容レベルまで追跡していきたい気持ちがあったので今回はコミット履歴について調べていくことにしました。

具体的に使用したのはRepository Statistics APIです。

また分析ツールですが、今回はその場限りのアドホックなデータ分析を行うためPython/Jupyter notebookを利用しました。

エンジニア以外のメンバーがデータをいじりたい時の事を考えるとGASを使う手もあったのですが、分析用データの前処理でPythonのPandasが使えると何かと助かるという事もあって今回はこの環境でいってみようと思います。

 

データ取得 > 前処理 > 可視化用のスクリプトの例

まずは会社(Organization)の全レポジトリの名前を確認しておきましょう。

なおaccess_tokenの部分はセキュリティ上伏せていますが、皆さんが手元で実行される際には GitHubのDeveloper settingsからPersonal access tokenを発行して該当部分に埋め込んでください。

import requests
import json
from datetime import datetime
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline

# 各種設定
owner = "moneyforward"
github_base_url = "https://api.github.com"
org_repositories_url = f"/orgs/{owner}/repos"
params = {
    "access_token": "***********"
}

# データ取得 > DataFrameに格納してレポジトリ名の一覧だけ確認する
dict_org_repositories = requests.get(github_base_url + org_repositories_url, params = params).json()
df_org_repositories = pd.DataFrame(dict_org_repositories)
print(df_org_repositories["name"])

続いて今名前を取得したレポジトリ達の中からいくつか選んで、直近52週間の1週間毎のコミット回数の推移を可視化していきます。

repositories = ["repo_a", "repo_b", "repo_c"]  # こちらも任意のレポジトリ名を入れてください
weekly_commits_dfs = {}

for repository in repositories:
    weekly_commits_url = f"/repos/{owner}/{repository}/stats/commit_activity"
    dict_weekly_commits = requests.get(github_base_url + weekly_commits_url, params = params).json()

    # 少し時間感覚を空けないとデータの取得が間に合わず次の処理が実行できません
    sleep(10) 

    # 前処理用にDataFrameに変換
    df_weekly_commits = pd.DataFrame(dict_weekly_commits)

    # 素のデータは日付がunixtime形式なので, グラフ化する時用に"年/月/日"の形式に変換しておく
    df_weekly_commits["datetime_week"] = df_weekly_commits["week"].apply(datetime.fromtimestamp).dt.strftime('%Y/%m/%d') 

    # コミット数の変化率も計算しておく
    df_weekly_commits["total_pct_change"] = df_weekly_commits["total"].pct_change()

    weekly_commits_dfs[repository] = df_weekly_commits

一旦ここまででデータの中身を確認します。

weekly_commits_dfs["repo_a"].head()

days列はリストになっていますが、これは要素の一つ一つが日曜から土曜の各曜日における合計コミット数を表しています。

このままでも必要なカラムを取り出せばグラフは作れるのですが、今回は全レポジトリのコミット数の推移をPandasのdf.plotが提供する積み上げ棒グラフでまとめて表示するために新たなDataFrameを用意します。

# 可視化に必要なデータだけ取り出し, 積み上げ棒グラフ用にデータの持ち方を変える
accum_bar_df = pd.DataFrame({"week": weekly_commits_dfs["repo_a"]["datetime_week"]})
for repository,  df in weekly_commits_dfs.items():
    accum_bar_df[repository] = df["total"]
    accum_bar_df[f"{repository}_change_rate"] = df["total_pct_change"]

# 中身はこんな感じ
accum_bar_df.head()

ここまで来ればもうプロットするだけです。コミット回数の推移は以下のような感じで。

fig, ax = plt.subplots()
accum_bar_df.plot(
                  kind = "bar",
                  x = "week",  
                  y = repositories,
                  stacked = True, 
                  figsize = (18, 8), 
                  legend=True,
                  title = "Weekly commit",
                  ax = ax
                  )
ax.set_xlabel("")
ax.set_ylabel("Commits")
plt.show()

変化率は普通に折れ線グラフで表示しましょう。

repositories_change_rate = [f"{repository}_change_rate" for repository in repositories]
fig, ax = plt.subplots()
accum_bar_df.plot(
                  x = "week",  
                  y = repositories_change_rate, 
                  figsize = (18, 8), 
                  legend=True,
                  title = "Weekly commit change rate",
                  ax = ax,
                  ylim = [-1, 3]
                  )

ax.set_xlabel("")
ax.set_ylabel("Change rate (%)")
plt.show()

普通にmatplotを使う場合と比べ、Pandasのdf.plotを利用すると沢山の項目をまとめて可視化する場合のスクリプトが非常に簡潔になるので良いですね。

コミット回数の推移

普通に折れ線でプロットするとこうなります。

コミット回数の変化率の推移

グラフから、repo_aは一時期非常に盛んに開発が行われ、ピーク時には通常の7倍近く( 1週間で700回以上! ) コミットされていましたが、最近は徐々にrepo_bとcの方の開発にウェイトが置かれ始めているのが見て取れます。

1月や5月の頭にコミット数の変化率のグラフが天を突き抜けてるのは完全に年末休みとGWの影響ですね笑

続いて上のグラフと同期間で時間帯によるコミット数の大小や曜日毎のコミット回数の差がないかを調べてみました。

先ほどと同様の手順でデータを取得しますが、データの取得先だけ /repos/:owner/:repo/stats/punch_card に変えます。 大体同じような手順になるのでコードは割愛して結果だけお見せします。

  • どの曜日も朝と昼過ぎに2回ピークがある様子

  • 月水木はrepo_aに似たダブルピークがある
  • 火水のコミット回数が他の曜日より明らかに多い

  • こちらは朝から夕方にかけて単調に増えていく。repo_aの開発チームより夜型の人が多いのかな...?

と、こんな感じで各プロダクトチームのエンジニアの生態が見えてきました。

それぞれのチーム毎に開発が捗る時間帯や曜日に微妙に差があるようなので、そういったゴールデンタイムにはエンジニアの皆さんにあまり会議など入れないようにして開発に集中させてあげた方が良いかもしれませんね。

 

まとめと今後の展望

簡単ではありましたが、GitHub APIを利用して各レポジトリへのコミット数に関するデータを取得・可視化し、各プロダクトチームの開発の調子を見たり、開発が捗っている曜日・時間帯などを知る事が出来ました。

今回は手始めにコミット回数のみを調べてみましたが、GitHub APIから取得できるデータはこれに限らず他にも沢山のデータ(Pull request回数、デプロイ回数、etc)が手に入ります。また今回のようなレポジトリ単位で集計されたデータだけでなくエンジニア一人一人についてのGitの使用履歴にまで分解し、コミットが生成される平均的な時間間隔などを計算できれば

「Aさんは今月のコミット時間間隔が先月比で5%短くなっているので開発スピードが上がってきている」

などといったエンジニアの開発力の伸び具合を定量的に知ることが出来るかも知れません。

今後はそういったより詳細な分析に手を伸ばしていこうと思います。

 

最後に

マネーフォワードでは、エンジニアを募集しています。 ご応募お待ちしています。

【採用サイト】 ■マネーフォワード採用サイトWantedly | マネーフォワード

【マネーフォワードのプロダクト】 ■自動家計簿・資産管理サービス『マネーフォワード ME』 iPhone,iPad Android

■ビジネス向けクラウドサービス『マネーフォワードクラウドシリーズ』 ・バックオフィス業務を効率化『マネーフォワードクラウド』会計ソフト『マネーフォワードクラウド会計』確定申告ソフト『マネーフォワードクラウド確定申告』請求書管理ソフト『マネーフォワードクラウド請求書』給与計算ソフト『マネーフォワードクラウド給与』経費精算ソフト『マネーフォワードクラウド経費』マイナンバー管理ソフト『マネーフォワードクラウドマイナンバー』資金調達サービス『マネーフォワードクラウド資金調達』

「しら」ずにお金が「たま」る 人生を楽しむ貯金アプリ『しらたま』 iPhone,iPad

おトクが飛び出すクーポンアプリ『tock pop トックポップ』

金融商品の比較・申し込みサイト『Money Forward Mall』

くらしの経済メディア『MONEY PLUS』

本業に集中できる新しいオンライン融資サービス『Money Forward BizAccel(マネーフォワード ビズアクセル)』