どういうこと?
会社でGitHub Copilotを使うにあたって、使用状況を把握して効果測定したい!というのは当然のモチベーションとしてあるのではと思う。GitHub CopilotにはMetics APIが用意されているのでこれを使えば統計情報を取ることができ、IDEでコード提案を受けた時の、
・提案されたコードの数
・受け入れたコードの数
・提案されたコードの行数
・受け入れたコードの行数
といったデータが取得できる。
元々、Copilot Metrics Viewerという可視化ツールが公開されてるので、これを使えば早いのだが、「APIから取得したデータを集計して表示するだけならCopilot Chat使って速攻で作れるだろ」と思いやってみた。(言語はPHP)
プロンプト ⇒ コード生成
Github CopilotのMetrics APIを使ってCopilotの使用状況の統計データを表示するプログラムを組んでください。
表示するデータは以下の4つです。
・提案された数
・受け入れた数
・提案された行数
・受け入れた行数
// GitHub Copilot Metrics APIのエンドポイント(組織名を含む)
$organization = "your-organization-name"; // 組織名を指定してください
$apiUrl = "https://api.github.com/orgs/$organization/copilot/metrics";
// APIトークン(GitHub Personal Access Tokenを使用)
$apiToken = "your_github_personal_access_token"; // トークンを設定してください
// cURLを使用してAPIリクエストを送信
$ch = curl_init($apiUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer $apiToken",
"User-Agent: GitHub Copilot Metrics Viewer"
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// HTTPステータスコードを確認
if ($httpCode !== 200) {
echo "APIリクエストに失敗しました。HTTPステータスコード: $httpCode\n";
exit;
}
// レスポンスをデコード
$data = json_decode($response, true);
// 統計情報を取得
if (isset($data['metrics'])) {
$metrics = $data['metrics'];
$suggestedCount = $metrics['suggested_count'] ?? 0;
$acceptedCount = $metrics['accepted_count'] ?? 0;
$suggestedLines = $metrics['suggested_lines'] ?? 0;
$acceptedLines = $metrics['accepted_lines'] ?? 0;
// 結果を表示
echo "提案された数: $suggestedCount\n";
echo "受け入れた数: $acceptedCount\n";
echo "提案された行数: $suggestedLines\n";
echo "受け入れた行数: $acceptedLines\n";
} else {
echo "統計情報を取得できませんでした。\n";
}
惜しい。レスポンスから統計情報を取得する部分の配列構造が適当すぎる。
Metrics APIのレスポンススキーマを理解していないので教えてあげる。
レスポンスの配列構造の例を以下に示します。
これを元にコードを修正してください。[
{
"date": "2024-06-24",
"total_active_users": 24,
"total_engaged_users": 20,
"copilot_ide_code_completions": {
"total_engaged_users": 20,
"languages": [
{(以下略)
// GitHub Copilot Metrics APIのエンドポイント(組織名を含む)
$organization = "your-organization-name"; // 組織名を指定してください
$apiUrl = "https://api.github.com/orgs/$organization/copilot/metrics";
// APIトークン(GitHub Personal Access Tokenを使用)
$apiToken = "your_github_personal_access_token"; // トークンを設定してください
// cURLを使用してAPIリクエストを送信
$ch = curl_init($apiUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer $apiToken",
"User-Agent: GitHub Copilot Metrics Viewer"
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// HTTPステータスコードを確認
if ($httpCode !== 200) {
echo "APIリクエストに失敗しました。HTTPステータスコード: $httpCode\n";
exit;
}
// レスポンスをデコード
$data = json_decode($response, true);
// 統計情報を取得
if (is_array($data) && !empty($data)) {
$totalSuggestions = 0;
$totalAcceptances = 0;
$totalLinesSuggested = 0;
$totalLinesAccepted = 0;
foreach ($data as $entry) {
if (isset($entry['copilot_ide_code_completions']['editors'])) {
foreach ($entry['copilot_ide_code_completions']['editors'] as $editor) {
if (isset($editor['models'])) {
foreach ($editor['models'] as $model) {
if (isset($model['languages'])) {
foreach ($model['languages'] as $language) {
$totalSuggestions += $language['total_code_suggestions'] ?? 0;
$totalAcceptances += $language['total_code_acceptances'] ?? 0;
$totalLinesSuggested += $language['total_code_lines_suggested'] ?? 0;
$totalLinesAccepted += $language['total_code_lines_accepted'] ?? 0;
}
}
}
}
}
}
}
// 結果を表示
echo "提案された数: $totalSuggestions\n";
echo "受け入れた数: $totalAcceptances\n";
echo "提案された行数: $totalLinesSuggested\n";
echo "受け入れた行数: $totalLinesAccepted\n";
} else {
echo "統計情報を取得できませんでした。\n";
}
いい感じ。
結果の出力はhtmlでお願いします。
// GitHub Copilot Metrics APIのエンドポイント(組織名を含む)
$organization = "your-organization-name"; // 組織名を指定してください
$apiUrl = "https://api.github.com/orgs/$organization/copilot/metrics";
// APIトークン(GitHub Personal Access Tokenを使用)
$apiToken = "your_github_personal_access_token"; // トークンを設定してください
// cURLを使用してAPIリクエストを送信
$ch = curl_init($apiUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer $apiToken",
"User-Agent: GitHub Copilot Metrics Viewer"
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// HTTPステータスコードを確認
if ($httpCode !== 200) {
echo "<p>APIリクエストに失敗しました。HTTPステータスコード: $httpCode</p>";
exit;
}
// レスポンスをデコード
$data = json_decode($response, true);
// 統計情報を取得
if (is_array($data) && !empty($data)) {
$totalSuggestions = 0;
$totalAcceptances = 0;
$totalLinesSuggested = 0;
$totalLinesAccepted = 0;
foreach ($data as $entry) {
if (isset($entry['copilot_ide_code_completions']['editors'])) {
foreach ($entry['copilot_ide_code_completions']['editors'] as $editor) {
if (isset($editor['models'])) {
foreach ($editor['models'] as $model) {
if (isset($model['languages'])) {
foreach ($model['languages'] as $language) {
$totalSuggestions += $language['total_code_suggestions'] ?? 0;
$totalAcceptances += $language['total_code_acceptances'] ?? 0;
$totalLinesSuggested += $language['total_code_lines_suggested'] ?? 0;
$totalLinesAccepted += $language['total_code_lines_accepted'] ?? 0;
}
}
}
}
}
}
}
// 結果をHTMLで表示
echo "<!DOCTYPE html>
<html lang='ja'>
<head>
<meta charset='UTF-8'>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<title>Copilot Metrics</title>
</head>
<body>
<h1>GitHub Copilot 使用状況</h1>
<ul>
<li>提案された数: $totalSuggestions</li>
<li>受け入れた数: $totalAcceptances</li>
<li>提案された行数: $totalLinesSuggested</li>
<li>受け入れた行数: $totalLinesAccepted</li>
</ul>
</body>
</html>";
} else {
echo "<p>統計情報を取得できませんでした。</p>";
}
おお?echoで全部吐いちゃってるけど、まぁいいか。
グラフも追加してほしいです
// GitHub Copilot Metrics APIのエンドポイント(組織名を含む)
$organization = "your-organization-name"; // 組織名を指定してください
$apiUrl = "https://api.github.com/orgs/$organization/copilot/metrics";
// APIトークン(GitHub Personal Access Tokenを使用)
$apiToken = "your_github_personal_access_token"; // トークンを設定してください
// cURLを使用してAPIリクエストを送信
$ch = curl_init($apiUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer $apiToken",
"User-Agent: GitHub Copilot Metrics Viewer"
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// HTTPステータスコードを確認
if ($httpCode !== 200) {
echo "<p>APIリクエストに失敗しました。HTTPステータスコード: $httpCode</p>";
exit;
}
// レスポンスをデコード
$data = json_decode($response, true);
// 統計情報を取得
if (is_array($data) && !empty($data)) {
$totalSuggestions = 0;
$totalAcceptances = 0;
$totalLinesSuggested = 0;
$totalLinesAccepted = 0;
foreach ($data as $entry) {
if (isset($entry['copilot_ide_code_completions']['editors'])) {
foreach ($entry['copilot_ide_code_completions']['editors'] as $editor) {
if (isset($editor['models'])) {
foreach ($editor['models'] as $model) {
if (isset($model['languages'])) {
foreach ($model['languages'] as $language) {
$totalSuggestions += $language['total_code_suggestions'] ?? 0;
$totalAcceptances += $language['total_code_acceptances'] ?? 0;
$totalLinesSuggested += $language['total_code_lines_suggested'] ?? 0;
$totalLinesAccepted += $language['total_code_lines_accepted'] ?? 0;
}
}
}
}
}
}
}
// 結果をHTMLで表示
echo "<!DOCTYPE html>
<html lang='ja'>
<head>
<meta charset='UTF-8'>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<title>Copilot Metrics</title>
<script src='https://cdn.jsdelivr.net/npm/chart.js'></script>
</head>
<body>
<h1>GitHub Copilot 使用状況</h1>
<ul>
<li>提案された数: $totalSuggestions</li>
<li>受け入れた数: $totalAcceptances</li>
<li>提案された行数: $totalLinesSuggested</li>
<li>受け入れた行数: $totalLinesAccepted</li>
</ul>
<canvas id='metricsChart' width='400' height='200'></canvas>
<script>
const ctx = document.getElementById('metricsChart').getContext('2d');
const metricsChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['提案された数', '受け入れた数', '提案された行数', '受け入れた行数'],
datasets: [{
label: 'GitHub Copilot Metrics',
data: [$totalSuggestions, $totalAcceptances, $totalLinesSuggested, $totalLinesAccepted],
backgroundColor: [
'rgba(75, 192, 192, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(153, 102, 255, 0.2)'
],
borderColor: [
'rgba(75, 192, 192, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(153, 102, 255, 1)'
],
borderWidth: 1
}]
},
options: {
scales: {
y: {
beginAtZero: true
}
}
}
});
</script>
</body>
</html>";
} else {
echo "<p>統計情報を取得できませんでした。</p>";
}
完成。
あとは組織名とトークンをこちらで入れてあげれば出来上がり。
成果物
所要時間:約10分