2155 文字
11 分
稼働表を手で書くのをやめた — コミット履歴だけで作ったら月9時間だった

常駐や業務委託で働いていると、月末にこれが来ます。

「今月の稼働表を出してください」

先月の自分が何時に働き始めて、何時まで作業していたか。思い出しながら30日分埋める作業です。しかも請求に直結するので、適当には書けません。

毎月やっているのに毎月面倒なので、すでにどこかに残っている記録から作れないかを試しました。結論から言うと作れましたが、最初のやり方は完全に間違っていました

発想: 稼働の痕跡はすでに残っている#

タイマーを押したり常駐ソフトを入れたりしなくても、働いていれば記録は残ります。

  • Slack に投稿した時刻
  • GitHub にコミットした時刻
  • チケットを更新した時刻
  • ドキュメントを編集した時刻

これらはすでに API で取れます。しかも過去に遡れる。「先月分を今から作る」ができるのが、タイマー式のツールとの決定的な違いです。

そこで、活動の時刻を集めて、塊ごとに「開始・終了・休憩」を推定する形にしてみました。

失敗1: コミット履歴だけでは、月の実働が9時間になった#

まず GitHub だけで試しました。自分の1か月分のコミットを取って、稼働表にしてみます。

結果がこれです。

稼働した日13日
活動イベント43件
推定の実働9時間01分

1か月で9時間。 さすがにそんなわけがありません。

理由は考えれば当たり前で、コミットは成果物であって作業時間ではないからです。

  • 3時間実装して、コミットは1回
  • 調査していた時間はコミットにならない
  • レビュー、打ち合わせ、環境構築、障害対応、どれも残らない
  • そもそも毎日コミットするとは限らない

エンジニアの仕事はコードを書くだけではないので、コミット履歴は稼働の一部しか写しません。「GitHub さえ繋げば稼働表ができる」は成立しませんでした。

失敗2: 深夜まで働くと、稼働が2日に割れる#

次に Slack を足しました。チャットは業務時間中ずっと発生するので、密度が段違いです。

ところが今度は別の問題が出ました。深夜1時まで作業した日の稼働表がこうなります。

2026-06-17 09:12 - 23:58 実働 13:20
2026-06-18 00:15 - 01:03 実働 0:48 休憩 14:00 ← ???

日付をまたいだ瞬間に別の日として切られ、しかも「00:15から01:03まで働いて、そのあと14時間休憩した」という珍妙な行ができます。

暦日で切っていたのが原因でした。人間の感覚では、深夜1時の作業は「前日の続き」です。

なので稼働日の始まりを 5:00 にしました。5時より前の活動は前日に属する扱いです。これで深夜作業が1行にまとまります。

調整したところ3つ#

1. ソースごとに前後の重みを変える#

活動時刻は「点」ですが、稼働は「線」です。点の前後をどれだけ稼働とみなすかを決める必要があります。

ここをソースごとに変えました

ソース
Slack0.50.5
GitHub3.00.5
チケット系1.00.5

コミットの前には作業時間があります。 チャットの返信は書いた瞬間が作業ですが、コミットは「3時間書いた結果」なので、前側を厚く取らないと実態に合いません。

倍率が妥当かは実データで確認しました。自分の6月のデータで、GitHub の前バッファを 0.5 から 3.0 に上げたときの増分がこれです。

実働の増加+8時間01分(+6.1%)
理論上の最大増加に対する割合25%

75%は、すでに Slack のセッションに含まれていました。 つまり大半のコミットは「チャットもしている時間帯」に打たれていて、二重計上にはなっていない。増えた8時間は「コミットしかしていない時間帯」=集中して書いていた時間です。

2. 休憩の判定は45分#

活動の空白がどれだけ続いたら「休憩」とみなすか。ここを45分にしました。

労働基準法では、労働時間が6時間を超えると45分以上、8時間を超えると1時間以上の休憩が要ります。45分は法定の最小単位なので、ここを閾値にすると「法的に休憩とみなせる長さの空白」が休憩になります。30分だと打ち合わせの移動や離席まで休憩にされ、実働が不当に短く出ます。

3. 「何をしていたか」は見出しだけ取る#

常駐先の稼働表には、時間の隣に作業内容の欄があることが多いです。ここも埋めたい。

ただし取るものを厳密に絞りました。

取る取らない
コミットメッセージSlack のメッセージ本文
チケットの件名チケットのコメント本文
Slack のチャンネル名
ドキュメントのファイル名

見出しは本人が自分の作業を説明するために書いたものですが、本文は他人との会話です。 ここを越えると、稼働表を作る道具から「監視ツール」に変わります。

粒度も調整しました。最初はコミットメッセージを1行ずつ出していたのですが、12回コミットした日に12行並んでも結局まとめ直すことになります。稼働表に書くのは「どの案件をやったか」なので、既定はリポジトリ名・プロジェクト名・チャンネル名にしました。

出さないと決めたもの: 金額#

残業の内訳(所定内・法定内残業・法定時間外・深夜・法定休日)は出します。ここは時間の分類なので、活動ログから機械的に決まります。

ただし割増率と金額は出しません

理由は、そこから先は労務の判断だからです。固定残業の扱い、休日の定義、単価の解釈は契約ごとに違います。推定値に金額を掛けた瞬間に、「これで請求していいのか」という判断を機械がしたことになる。時間の内訳までを出して、金額は人が決める線を引きました。

できたもの#

そういう形で作ったのがこれです。

https://w.doany.io

Slack / GitHub / GitLab / Backlog / Jira / OpenProject / Redmine / Google ドライブの活動時刻から、日別の開始・終了・休憩・実働を推定して、稼働表の下書きを出します。CSV とスプレッドシート貼り付け用の出力まで含みます。

特徴は2つです。

  • PC に常駐ソフトを入れない。 客先常駐だと監視エージェントを入れられない現場が多いので、サーバー側の API ログだけを読む形にしています
  • 事前の準備なしで過去に遡れる。 記録を取り始めていなくても、すでに残っているログから先月分を再構成できます

今月と先月分は無料で作れます。

おわりに#

やってみて一番の収穫は、「コミットだけでは月9時間にしかならない」を数字で見たことでした。

作る前は「エンジニアなんだから GitHub を繋げば十分だろう」と思っていました。実際にやると、それはコードを書いている時間しか仕事とみなさないという前提でした。調査も打ち合わせもレビューも稼働です。

稼働表を自動で作るというのは、「何を稼働とみなすか」を決める作業でした。そこを外すと、動いてはいるが数字が使い物にならないものができます。

稼働表を手で書くのをやめた — コミット履歴だけで作ったら月9時間だった
https://doany.io/posts/worklog-from-logs/
作者
丸山 竜輝
公開日
2026-08-06
ライセンス
CC BY-NC-SA 4.0