Skip to main content

使用 Copilot 指标 API 分析随时间推移的使用情况

了解如何连接到 API、存储数据以及分析使用趋势。

谁可以使用此功能?

Organization owners, enterprise owners, and billing managers

GitHub Copilot Business or GitHub Copilot Enterprise

简介

可使用 用于 Copilot 指标的 REST API 终结点 查看用户采用 GitHub Copilot 的趋势。 在推出 GitHub Copilot 的过程中,查看这些趋势非常有用,可以检查用户是否使用了分配的许可证,了解用户使用了哪些功能,并评估公司启用计划对开发者的影响。

该 API 包括:

  • 过去 28 天的数据
  • 活动用户数和参与用户数
  • 按语言和 IDE 细分
  • 查看企业、组织或团队指标的选项

如果当前使用 GitHub Copilot 使用指标的 REST API 终结点,建议尽快迁移到 用于 Copilot 指标的 REST API 终结点

本指南演示如何查询 API、存储数据,以及如何分析每周用户数的变化趋势。 本指南中的示例使用组织的终结点,但你可以根据需求调整示例。

关于终结点可用性

终结点可用于获取企业、组织、组织团队或企业团队的数据。

  • 如果你是常规组织或企业的成员,并拥有 GitHub Copilot Business 或 GitHub Copilot Enterprise 订阅,可以使用适用于企业、组织或组织团队的终结点****。 除非你已在预览版中注册,否则无权访问企业团队。
  • 如果你为 GitHub Copilot Business 使用了专用企业帐户(即无法创建组织的企业帐户),你可以使用适用于企业或企业团队的终结点****。

先决条件

  • 必须为企业或组织启用 Copilot 指标 API 访问策略****。 请参阅“管理组织中的 Copilot 策略”或“管理企业中 Copilot 的策略和功能”。
  • 要查询的组织、企业或团队必须有足够的活动 Copilot 用户。 仅当指定日有五名或更多名成员拥有活动 Copilot 许可证时,API 才会返回该日的结果****。
  • 在此示例中,我们将创建一个 JavaScript 脚本,用于查询和分析数据。 要在本地运行此脚本,必须安装 Node.js,然后使用 npm install -g octokit 安装 Octokit.js SDK

1.创建 personal access token

以我们的示例为例,要获取一个组织的指标,我们将创建一个带有 manage_billing:copilot 范围的 personal access token (classic)。 请参阅“管理个人访问令牌”。

如果使用另一个终结点,可能需要不同的范围。 请参阅“用于 Copilot 指标的 REST API 终结点”。

2.连接到 API

我们将从脚本中调用 API 并将响应保存为一个变量。 然后,我们可以在外部存储数据并分析数据的趋势。

以下示例使用适用于 JavaScript 的 Octokit 客户端。 可以使用其他方法调用 API,例如 cURL 或 GitHub CLI。

示例

在此示例中:

  • 将 YOUR_TOKEN 替换为 personal access token。
  • 将 YOUR_ORG 替换为组织名称,例如 octo-org
JavaScript
import { Octokit } from "octokit";

Import Octokit

const octokit = new Octokit({
  auth: 'YOUR_TOKEN'
});
const org = 'YOUR_ORG';

Set your token and organization

/*
const team = 'YOUR_TEAM';
const enterprise = 'YOUR_ENTERPRISE';
const entTeam = 'YOUR_ENTERPRISE_TEAM';
*/

Set other variables if required for the endpoint you're using

async function orgMetrics() {
  const resp = await octokit.request(`GET /orgs/${org}/copilot/metrics`, {
    org: 'ORG',
    headers: {
      'X-GitHub-Api-Version': '2022-11-28'
    }
  });
  const copilotUsage = resp.data;
  console.log(copilotUsage);
  }

Call the API

orgMetrics();

Call the function

// Import Octokit
import { Octokit } from "octokit";

// Set your token and organization
const octokit = new Octokit({
  auth: 'YOUR_TOKEN'
});
const org = 'YOUR_ORG';

// Set other variables if required for the endpoint you're using
/*
const team = 'YOUR_TEAM';
const enterprise = 'YOUR_ENTERPRISE';
const entTeam = 'YOUR_ENTERPRISE_TEAM';
*/

// Call the API
async function orgMetrics() {
  const resp = await octokit.request(`GET /orgs/${org}/copilot/metrics`, {
    org: 'ORG',
    headers: {
      'X-GitHub-Api-Version': '2022-11-28'
    }
  });

  const copilotUsage = resp.data;

  console.log(copilotUsage);
  }

// Call the function
orgMetrics();

在本地运行脚本

要在本地测试脚本,请将文件另存为 copilot.mjs,然后运行 node copilot.mjs

Important

.mjs 文件类型非常重要****。 import { Octokit } 语句可能不适用于常规 .js 文件。

你应会在终端中看到类似以下的 JSON 数组输出。

[
  {
    date: '2024-11-07',
    copilot_ide_chat: { editors: [Array], total_engaged_users: 14 },
    total_active_users: 28,
    copilot_dotcom_chat: { models: [Array], total_engaged_users: 4 },
    total_engaged_users: 28,
    copilot_dotcom_pull_requests: { total_engaged_users: 0 },
    copilot_ide_code_completions: { editors: [Array], total_engaged_users: 22 }
  },
...

3.存储数据

要分析超过 28 天的趋势,需要执行以下操作:

  • 每天调用 API,可以使用 cron 作业或计划的 GitHub Actions 工作流。
  • 在本地或使用数据库服务(如 MySQL)存储数据。
  • 查询数据以确定随时间推移的趋势。

示例

在此示例中,我们会将数据保存到本地 .json 文件。 为此,我们将导入一些用于处理文件的模块,并更新 orgMetrics 函数以保存响应数据。

该函数会保存每天返回的新数据,而不会覆盖文件中的旧数据。

新步骤用粗体注明****。

JavaScript
import { Octokit } from "octokit";

Import Octokit

import path from 'path';
import fs from 'fs';
import { fileURLToPath } from 'url';
import { dirname } from 'path';

Import modules for working with files

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

Declare variables for working with files

const octokit = new Octokit({
  auth: 'YOUR_TOKEN'
});
const org = 'YOUR_ORG';

Set your token and organization

async function orgMetrics() {
  const resp = await octokit.request(`GET /orgs/${org}/copilot/metrics`, {
    org: 'ORG',
    headers: {
      'X-GitHub-Api-Version': '2022-11-28'
    }
  });
  const copilotUsage = resp.data;

Call the API

  const dataFilePath = path.join(__dirname, 'copilotMetricsData.json');

Define the path to the local file where data will be stored

  let existingData = [];
  if (fs.existsSync(dataFilePath)) {
    const fileContent = fs.readFileSync(dataFilePath, 'utf8');
    existingData = JSON.parse(fileContent);
  }

Read existing data from the file, if it exists

  const newData = copilotUsage.filter(entry => !existingData.some(existingEntry => existingEntry.date === entry.date));

Filter out the new data that is not already in the existing data

  if (newData.length > 0) {
    existingData = existingData.concat(newData);

Append new data to the existing data

    fs.writeFileSync(dataFilePath, JSON.stringify(existingData, null, 2));
    console.log(`Saved ${newData.length} new entries.`);
  } else {
    console.log('No new data to save.');
  }
}

Save the updated data back to the file

orgMetrics();

Call the function

// Import Octokit
import { Octokit } from "octokit";

// **Import modules for working with files**
import path from 'path';
import fs from 'fs';
import { fileURLToPath } from 'url';
import { dirname } from 'path';

// **Declare variables for working with files**
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

// Set your token and organization
const octokit = new Octokit({
  auth: 'YOUR_TOKEN'
});

const org = 'YOUR_ORG';

// Call the API
async function orgMetrics() {
  const resp = await octokit.request(`GET /orgs/${org}/copilot/metrics`, {
    org: 'ORG',
    headers: {
      'X-GitHub-Api-Version': '2022-11-28'
    }
  });

  const copilotUsage = resp.data;

  // **Define the path to the local file where data will be stored**
  const dataFilePath = path.join(__dirname, 'copilotMetricsData.json');

  // **Read existing data from the file, if it exists**
  let existingData = [];
  if (fs.existsSync(dataFilePath)) {
    const fileContent = fs.readFileSync(dataFilePath, 'utf8');
    existingData = JSON.parse(fileContent);
  }

  // **Filter out the new data that is not already in the existing data**
  const newData = copilotUsage.filter(entry => !existingData.some(existingEntry => existingEntry.date === entry.date));

  // **Append new data to the existing data**
  if (newData.length > 0) {
    existingData = existingData.concat(newData);

    // **Save the updated data back to the file**
    fs.writeFileSync(dataFilePath, JSON.stringify(existingData, null, 2));
    console.log(`Saved ${newData.length} new entries.`);
  } else {
    console.log('No new data to save.');
  }
}

// Call the function
orgMetrics();

在本地运行脚本

使用 node copilot.mjs 运行脚本后,目录中应有一个名为 copilotMetricsData.json 的新文件。 该文件应包含 API 响应中的数据。

如果明天再次运行该脚本,它应该只会将新一天的数据保存到文件中。

可以使用 API 返回的数据来识别过去 28 天的趋势,或者如果你已经存储了之前的 API 调用数据,则可以分析更长时间的趋势。

示例

在以下示例中,我们更新了 orgMetrics 函数,以提取每周活动用户和参与用户的总数和平均数。 然后,我们可以使用这些数据来跟踪随时间变化的情况。 此示例使用直接从 API 返回的数据,并且不需要存储的数据。

新步骤用粗体注明****。

JavaScript
async function orgMetrics() {
  const resp = await octokit.request(`GET /orgs/${org}/copilot/metrics`, {
    org: 'ORG',
    headers: {
      'X-GitHub-Api-Version': '2022-11-28'
    }
  });
  const copilotUsage = resp.data;

Call the API

  let userTrends ={
    week1: {
      days:0,
      activeUsers:0,
      engagedUsers:0,
    },
    week2: {
      days:0,
      activeUsers:0,
      engagedUsers:0,
    },
    week3: {
      days:0,
      activeUsers:0,
      engagedUsers:0,
    },
    week4: {
      days:0,
      activeUsers:0,
      engagedUsers:0,
    },
  };

Create an object to store data for each week

 for (let i =0; i<copilotUsage.length; i++) {

Iterate over the data

    const week = Math.ceil((i+1)/7);

Determine the week number (1-4) based on the index

    userTrends[`week${week}`].days += 1;
    userTrends[`week${week}`].activeUsers += copilotUsage[i].total_active_users;
    userTrends[`week${week}`].engagedUsers += copilotUsage[i].total_engaged_users;
  }

Increment userTrends for the current week

 for (const week in userTrends) {
  userTrends[week].avgActiveUsers = (userTrends[week].activeUsers / userTrends[week].days).toFixed(2);
  userTrends[week].avgEngagedUsers = (userTrends[week].engagedUsers / userTrends[week].days).toFixed(2);
  }

Calculate the average number of active and engaged users per day for each week, rounded to two decimal places

  console.log(userTrends);
}

Output to the console

// Call the API
async function orgMetrics() {
  const resp = await octokit.request(`GET /orgs/${org}/copilot/metrics`, {
    org: 'ORG',
    headers: {
      'X-GitHub-Api-Version': '2022-11-28'
    }
  });

  const copilotUsage = resp.data;

  // **Create an object to store data for each week**
  let userTrends ={
    week1: {
      days:0,
      activeUsers:0,
      engagedUsers:0,
    },
    week2: {
      days:0,
      activeUsers:0,
      engagedUsers:0,
    },
    week3: {
      days:0,
      activeUsers:0,
      engagedUsers:0,
    },
    week4: {
      days:0,
      activeUsers:0,
      engagedUsers:0,
    },
  };

 // **Iterate over the data**
 for (let i =0; i<copilotUsage.length; i++) {
    // **Determine the week number (1-4) based on the index**
    const week = Math.ceil((i+1)/7);
    // **Increment userTrends for the current week**
    userTrends[`week${week}`].days += 1;
    userTrends[`week${week}`].activeUsers += copilotUsage[i].total_active_users;
    userTrends[`week${week}`].engagedUsers += copilotUsage[i].total_engaged_users;
  }

 // **Calculate the average number of active and engaged users per day for each week, rounded to two decimal places**
 for (const week in userTrends) {
  userTrends[week].avgActiveUsers = (userTrends[week].activeUsers / userTrends[week].days).toFixed(2);
  userTrends[week].avgEngagedUsers = (userTrends[week].engagedUsers / userTrends[week].days).toFixed(2);
  }

  // Output to the console
  console.log(userTrends);
}

在本地运行脚本

使用 node copilot.mjs 运行脚本后,终端中应会显示如下所示的输出。

{
  week1: {
    days: 7,
    activeUsers: 174,
    engagedUsers: 174,
    avgActiveUsers: '24.86',
    avgEngagedUsers: '24.86'
  },
  week2: {
    days: 7,
    activeUsers: 160,
    engagedUsers: 151,
    avgActiveUsers: '22.86',
    avgEngagedUsers: '21.57'
  },
  week3: {
    days: 7,
    activeUsers: 134,
    engagedUsers: 123,
    avgActiveUsers: '19.14',
    avgEngagedUsers: '17.57'
  },
  week4: {
    days: 6,
    activeUsers: 143,
    engagedUsers: 132,
    avgActiveUsers: '23.83',
    avgEngagedUsers: '22.00'
  }
}