常駐や業務委託で働いていると、月末にこれが来ます。
「今月の稼働表を出してください」
先月の自分が何時に働き始めて、何時まで作業していたか。思い出しながら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:202026-06-18 00:15 - 01:03 実働 0:48 休憩 14:00 ← ???日付をまたいだ瞬間に別の日として切られ、しかも「00:15から01:03まで働いて、そのあと14時間休憩した」という珍妙な行ができます。
暦日で切っていたのが原因でした。人間の感覚では、深夜1時の作業は「前日の続き」です。
なので稼働日の始まりを 5:00 にしました。5時より前の活動は前日に属する扱いです。これで深夜作業が1行にまとまります。
調整したところ3つ
1. ソースごとに前後の重みを変える
活動時刻は「点」ですが、稼働は「線」です。点の前後をどれだけ稼働とみなすかを決める必要があります。
ここをソースごとに変えました。
| ソース | 前 | 後 |
|---|---|---|
| Slack | 0.5 | 0.5 |
| GitHub | 3.0 | 0.5 |
| チケット系 | 1.0 | 0.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行並んでも結局まとめ直すことになります。稼働表に書くのは「どの案件をやったか」なので、既定はリポジトリ名・プロジェクト名・チャンネル名にしました。
出さないと決めたもの: 金額
残業の内訳(所定内・法定内残業・法定時間外・深夜・法定休日)は出します。ここは時間の分類なので、活動ログから機械的に決まります。
ただし割増率と金額は出しません。
理由は、そこから先は労務の判断だからです。固定残業の扱い、休日の定義、単価の解釈は契約ごとに違います。推定値に金額を掛けた瞬間に、「これで請求していいのか」という判断を機械がしたことになる。時間の内訳までを出して、金額は人が決める線を引きました。
できたもの
そういう形で作ったのがこれです。
Slack / GitHub / GitLab / Backlog / Jira / OpenProject / Redmine / Google ドライブの活動時刻から、日別の開始・終了・休憩・実働を推定して、稼働表の下書きを出します。CSV とスプレッドシート貼り付け用の出力まで含みます。
特徴は2つです。
- PC に常駐ソフトを入れない。 客先常駐だと監視エージェントを入れられない現場が多いので、サーバー側の API ログだけを読む形にしています
- 事前の準備なしで過去に遡れる。 記録を取り始めていなくても、すでに残っているログから先月分を再構成できます
今月と先月分は無料で作れます。
おわりに
やってみて一番の収穫は、「コミットだけでは月9時間にしかならない」を数字で見たことでした。
作る前は「エンジニアなんだから GitHub を繋げば十分だろう」と思っていました。実際にやると、それはコードを書いている時間しか仕事とみなさないという前提でした。調査も打ち合わせもレビューも稼働です。
稼働表を自動で作るというのは、「何を稼働とみなすか」を決める作業でした。そこを外すと、動いてはいるが数字が使い物にならないものができます。