作者:Xuefeng Yin

排版:Alan Wang

Copilot Usage Advanced Dashboard 是为了充分利用 GitHub Copilot API 中的几乎所有数据,用到的 API 有:

形成单一的数据面板展示,从不同的维度展现 Copilot 在多个 Organzations 和 Teams 中的使用情况。特性概括如下:

  • 对数据进行持久化存储到 Elasticsearch 中,并基于 Grafana 进行数据可视化,而不仅仅是展示过去的28天数据。因此,可以自由选择期望进行数据可视化的时间段,如过去一整年、或者特定的月份。

  • 所有存储的数据都包含了 Organization 和 Team 字段,方便通过变量过滤器进行数据筛选。

  • 对每一份数据生成唯一 hash key,每次获取最新数据时,会更新已经存储的数据。

  • 可根据实际需求,对 Grafana 的 dashboards 中的 visualizations 进行调整、删除。

  • 可以基于 Grafana 的内置告警功能,设定 alert 规则,对一些不合适的使用行为进行告警,比如对长期不活跃的用户发送告警信息。

  • 可以方便的与第三方系统集成,不论是从 Elasticsearch 中抽取数据到别的数据可视化平台进行数据可视化,或者在 Copilot Usage Advanced Dashboard 中添加别的数据源进行联合数据可视化。

Online Demo Environment✨

设计了2款 dashboards,二者可以在 Grafana 中同时存在。

在这里插入图片描述

Copilot Usage Advanced Dashboard

Copilot Metrics Viewer 兼容 dashboard
如果你很熟悉 copilot-metrics-viewer 项目,那么请体验这个 dashboard,并在后续的安装中使用此 dashboard。

  • 地址:http://20.89.179.123:3000/d/be7hpbvvhst8gc/copilot-usage-advanced-dashboard

  • 用户名:demouser

  • 密码:demouser

在这里插入图片描述

Copilot Usage Advanced Dashboard Original

新设计 dashboard

  • 地址:http://20.89.179.123:3000/d/a98455d6-b401-4a53-80ad-7af9f97be6f4/copilot-usage-advanced-dashboard-original

  • 用户名:demouser

  • 密码:demouser

在这里插入图片描述

条件变量

支持四种过滤条件,分别是:

  • Organzation

  • Team

  • Language

  • Editor

变量的选择会动态关联到数据
在这里插入图片描述

特性

Copilot Usage Advanced Dashboard

1 Organization

先基于 List teams of an onganization 获取 Organization 下的所有 teams,然后基于 Get a summary of Copilot usage for a team,对 Organization 下所有的 teams 的数据求和并计算,得到完整的 Organization 层面数据。

  • Acceptance Rate Average = sum(total_acceptances_count) / sum(total_suggestions_count)

  • Cumulative Number of Acceptence (Count) = sum(total_acceptances_count)

  • Cumulative Number of Suggestions (Count) = sum(total_suggestions_count)

  • Cumulative Number of Lines of Code Accepted = sum(total_lines_accepted)

  • Acceptance Rate (%) = total_acceptances_count / total_suggestions_count

  • Total Active Users = total_active_users

  • Total Suggestions & Acceptances Count = total_suggestions_count & total_acceptances_count

  • Total Lines Suggested & Accepted = total_lines_suggested & total_lines_accepted

在这里插入图片描述

2 Teams

基于Get a summary of Copilot usage for a team中的 breakdown 数据进行分析,对数据按照 Teams 进行数据聚合,得到不同的 Teams 的数据对比。

  • Number of Teams = unique_count(team_slug)

  • Top Teams by Accepted Prompts = sum(acceptances_count).groupby(team_slug)

  • Top Teams by Acceptance Rate = sum(acceptances_count).groupby(team_slug) / sum(suggestions_count).groupby(team_slug)

  • Teams Breakdown = sum(*).groupby(team_slug)

在这里插入图片描述

3 Languages

基于Get a summary of Copilot usage for a team中的breakdown数据进行分析,对数据按照Languages进行数据聚合,得到不同的Languages的数据对比。

  • Number of Languages= unique_count(language)

  • Top Languages by Accepted Prompts = sum(acceptances_count).groupby(language)

  • Top Languages by Acceptance Rate = sum(acceptances_count).groupby(language) / sum(suggestions_count).groupby(language)

  • Languages Breakdown = sum(*).groupby(language)

在这里插入图片描述

4 Editors

基于 Get a summary of Copilot usage for a team 中的 breakdown 数据进行分析,对数据按照 Editors 进行数据聚合,得到不同的 Editors 的数据对比。

  • Number of Editors = unique_count(editor)

  • Top Editors by Accepted Prompts = sum(acceptances_count).groupby(editor)

  • Top Editors by Acceptance Rate = sum(acceptances_count).groupby(editor) / sum(suggestions_count).groupby(editor)

  • Editors Breakdown = sum(*).groupby(editor)

在这里插入图片描述

5 Copilot Chat

基于 Get a summary of Copilot usage for a team 的数据进行分析,得到 Copilot Chat 的使用情况。

  • Acceptance Rate Average = sum(total_chat_acceptances) / sum(total_chat_turns)

  • Cumulative Number of Acceptances = sum(total_chat_acceptances)

  • Cumulative Number of Turns = sum(total_chat_turns)

  • Total Acceptances | Total Turns Count = total_chat_acceptances | total_chat_turns

  • Total Active Copilot Chat Users = total_active_chat_users

在这里插入图片描述

6 Seat Analysis

基于 Get Copilot seat information and settings for an organization 以及 List all Copilot seat assignments for an organization 的数据分析,把席位分配情况和使用情况进行统一呈现。

  • Copilot Plan Type = count(seats).groupby(plan_type)

  • Total = seat_breakdown.total

  • Active in this Cycle = seat_breakdown.active_this_cycle

  • Assigned But Never Used = last_activity_at.isnan()

  • Inactive in this Cycle = seat_breakdown.inactive_this_cycle

  • Ranking of Inactive Users ( ≥ 2 days ) = today - last_activity_at

  • All assigned seats = *

在这里插入图片描述

7 Breakdown Heatmap

基于 Get a summary of Copilot usage for a team 中的breakdown 数据进行分析,从 Languages 和 Editors 二个维度进行数据分析。可以清晰的看到什么样的 Languages 和 Editors 的组合可以实现最好的 Copilot 使用效果。

  • Active Users Count (Group by Language) = active_users.groupby(language)

  • Accept Rate by Count (%) = sum(acceptances_count).groupby(language) / sum(suggestions_count).groupby(language)

  • Accept Rate by Lines (%) = sum(lines_accepted).groupby(language) / sum(lines_suggested).groupby(language)

  • Active Users Count (Group by Editor) = active_users.groupby(editor)

  • Accept Rate by Count (%) = sum(acceptances_count).groupby(editor) / sum(suggestions_count).groupby(editor)

  • Accept Rate by Lines (%) = sum(lines_accepted).groupby(editor) / sum(lines_suggested).groupby(editor)

在这里插入图片描述

Copilot Usage Advanced Dashboard Original

1 Copilot Seat Info & Top Languages
  • 您可以查看席位分布情况、企业版还是商务版?以及总体激活趋势。对于不使用 Copilot 的用户,将根据不活动时间长短进行排名,并列出从未激活的用户。

  • 根据使用情况对语言和团队进行排名

在这里插入图片描述

2 Copilot Usage Total Insight

您可以根据计数、行数和聊天量分析推荐总数和采用率趋势。
在这里插入图片描述

3 Copilot Usage Breakdown Insight

你可以分析 Copilot 在不同语言,不同编辑器组合下的效果。
在这里插入图片描述

特别说明

本文所描述一切内容都是基于 all-in-one 架构。在生产环境中,可以根据实际需求,拆分成分布式架构。

原理

在这里插入图片描述

技术栈

依赖的技术栈:

  • VM

  • Docker

  • Elasticsearch

  • Grafana

  • Python3

部署

所有操作在 VM 中执行

先决条件

一切都在本地并且免费(VM 除外)

唯一需要的是:

  • 一个 VM

    • 内存:建议 16G

    • 操作系统:Ubuntu 22.04(推荐,其他操作系统除了安装 Docker 外没有区别)

    • 端口:需要释放 3000 端口供 Grafana 使用,22 端口可以自行确定。

其他一切都基于现有的东西,或者基于开源软件,无需额外费用,例如:

  • 启用了 Copilot 的 GitHub Organzations(我相信,您已经拥有它)

  • Docker(社区版本就足够了)

  • Elasticsearch(社区版本就足够了)

  • Grafana(社区版本就足够了,不需要 Grafana 云帐户)

  • 从此项目构建的 CPUAD-Updater(MIT 许可证)

Docker

安装方式参考 Install Docker Engine,对于 Ubuntu 22.04,可以使用如下命令:

apt install docker.io

验证

docker version

得到如下内容,表示 ok

Client:
 Version:           24.0.7
 API version:       1.43
 Go version:        go1.21.1
 Git commit:        24.0.7-0ubuntu2~22.04.1
 Built:             Wed Mar 13 20:23:54 2024
 OS/Arch:           linux/amd64
 Context:           default
Server:
 Engine:
  Version:          24.0.7
  API version:      1.43 (minimum version 1.12)
  Go version:       go1.21.1
  Git commit:       24.0.7-0ubuntu2~22.04.1
  Built:            Wed Mar 13 20:23:54 2024
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.7.12
  GitCommit:
 runc:
  Version:          1.1.12-0ubuntu2~22.04.1
  GitCommit:
 docker-init:
  Version:          0.19.0
  GitCommit:

下载源码

所有工作内容都放在 /srv 目录中,点击下载 zip 压缩包,解压后重命名文件夹名称为 copilot-usage-advanced-dashboard,或者直接 git clone

cd /srv
git clone https://github.com/satomic/copilot-usage-advanced-dashboard.git
cd copilot-usage-advanced-dashboard

验证

ls -ltr

得到如下内容,表示 ok

total 64
-rw-r--r-- 1 root root   100 Dec 16 11:22 fetch.sh
-rw-r--r-- 1 root root    56 Dec 16 11:22 docker_build.sh
-rw-r--r-- 1 root root  1063 Dec 16 11:22 LICENSE
-rw-r--r-- 1 root root  1031 Dec 16 11:22 Dockerfile
-rw-r--r-- 1 root root   193 Dec 16 11:22 push.sh
drwxr-xr-x 2 root root  4096 Dec 16 11:22 mapping
-rw-r--r-- 1 root root    22 Dec 16 11:32 requirements.txt
-rw-r--r-- 1 root root   996 Dec 16 13:44 log_utils.py
drwxr-xr-x 2 root root  4096 Dec 17 00:18 grafana
-rw-r--r-- 1 root root  2571 Dec 17 00:18 gen_grafana_model.py
-rw-r--r-- 1 root root 22500 Dec 17 01:40 main.py

Elasticsearch

安装

如果你已经有了 ES,那么可以跳过本步骤,直接到下一步。
ES 不会暴露到 VM 的外部,因此不用开启 xpack.security.enabled

  1. 为 Elasticsearch 创建数据持久化目录和配置文件目录:
mkdir -p /srv/elasticsearch/data /srv/elasticsearch/confi
  1. 并授予所有用户读写权限。
chmod -R a+rw /srv/elasticsearch
  1. /srv/elasticsearch/config/ 目录下创建 elasticsearch.yml 配置文件:
cat >> /srv/elasticsearch/config/elasticsearch.yml << EOF
network.host: 0.0.0.0
node.name: single-node
cluster.name: es-docker-cluster
path.data: /usr/share/elasticsearch/data
path.logs: /usr/share/elasticsearch/logs
discovery.type: single-node
bootstrap.memory_lock: true
EOF
  1. 使用以下命令启动 Elasticsearch,并绑定数据目录和配置文件:
docker run -itd --restart always --name es \
  -p 9200:9200 \
  -e "xpack.security.enabled=false" \
  -e "ES_JAVA_OPTS=-Xms4g -Xmx4g" \
  -v /srv/elasticsearch/data:/usr/share/elasticsearch/data \
  -v /srv/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml:ro \
  docker.elastic.co/elasticsearch/elasticsearch:8.17.0
  1. 访问测试
curl http://localhost:9200

得到如下内容,表示 ok

{
    "name": "single-node",
    "cluster_name": "es-docker-cluster",
    "cluster_uuid": "oO3mfjYWTZ6VZFSClDiSLA",
    "version": {
        "number": "8.17.0",
        "build_flavor": "default",
        "build_type": "docker",
        "build_hash": "2b6a7fed44faa321997703718f07ee0420804b41",
        "build_date": "2024-12-11T12:08:05.663969764Z",
        "build_snapshot": false,
        "lucene_version": "9.12.0",
        "minimum_wire_compatibility_version": "7.17.0",
        "minimum_index_compatibility_version": "7.0.0"
    },
    "tagline": "You Know, for Search"
}
创建 index
  1. 确认当前在正确的路径中
cd /srv/copilot-usage-advanced-dashboard
  1. 执行脚本,创建 index
bash create_es_indexes.sh

得到如下内容,表示 ok

{"acknowledged":true,"shards_acknowledged":true,"index":"copilot_usage_total"}
{"acknowledged":true,"shards_acknowledged":true,"index":"copilot_usage_breakdown"}
{"acknowledged":true,"shards_acknowledged":true,"index":"copilot_usage_breakdown_chat"}
{"acknowledged":true,"shards_acknowledged":true,"index":"copilot_seat_info_settings"}
{"acknowledged":true,"shards_acknowledged":true,"index":"copilot_seat_assignments"}
  1. 检查
curl -X GET http://localhost:9200/_cat/indices?v

得到如下内容,表示 ok

health status index                        uuid                   pri rep docs.count docs.deleted store.size pri.store.size dataset.size
yellow open   copilot_usage_total          XrOEfAngTS60VsuUz3Lbrw   1   1          0            0       227b           227b         227b
yellow open   copilot_seat_info_settings   WtOBdBNUQRqua7wi7VANeQ   1   1          0            0       227b           227b         227b
yellow open   copilot_
seat
_assignments     lK5t4SwASZizPQ_
W4NX4KQ   1   1          0            0       227b           227b         227b
yellow open   copilot_usage_breakdown      xE6tkg5GQEOP-EP8pwAkYg   1   1          0            0       227b           227b         227b
yellow open   copilot_usage_breakdown_chat 6R_1cdlIQQOCv4BoHPqXCw   1   1          0            0       227b           227b         227b

Grafana

安装

如果你已经有了 Grafana,那么可以跳过本步骤,直接到下一步。

  1. 创建数据路径
mkdir -p /srv/grafana/data
chmod -R a+rw /srv/grafana/data
  1. 启动
docker run  -itd --restart always --name=grafana \
  --net=host \
  -p 3000:3000 \
  -v /srv/grafana/data:/var/lib/grafana \
  -e "GF_LOG_LEVEL=debug" \
  grafana/grafana:11.4.0
  1. 访问 Grafana
  • 访问地址:http://<PUBLIC_IP_OF_YOUR_VM>:3000

  • 默认用户名密码为 admin / admin,请修改密码

创建 Admin Token
  1. 管理员访问 Administration → Users and access → Service accounts
    在这里插入图片描述
  2. 输入 Display name,Role 选择 Admin,点击 Create
    在这里插入图片描述
  3. 点击 Add service account token
    在这里插入图片描述
  4. 点击 Generate token
    在这里插入图片描述
  5. Copy to clipboard and close
    在这里插入图片描述
  6. 现在,你获得了你的 Grafana Token “<your_grafana_token>”,请保存后它,并设置为VM中的环境变量,接下来步骤会用到。
export GRAFANA_TOKEN="<your_grafana_token>"
通过 API 添加 Data sources
  1. 确认当前在正确的路径中
cd /srv/copilot-usage-advanced-dashboard
  1. 执行脚本,添加 data sources
bash add_grafana_data_sources.sh
  1. 访问 Grafana UI,确认添加成功
    在这里插入图片描述
生成 Dashboard Json Model
  1. 确认当前在正确的路径中
cd /srv/copilot-usage-advanced-dashboard
  1. 执行脚本,生成 Grafana json 模型,如下2个命令,执行其中的一条就可以
# 生成 Copilot Usage Advanced Dashboard
python3 gen_grafana_model.py --template=grafana/dashboard-template.json
# Copilot Usage Advanced Dashboard Original
python3 gen_grafana_model.py --template=grafana/dashboard-template-original.jso

得到输出

Model saved to grafana/dashboard-model-2024-12-17.json, please import it to Grafana
导入产生的 Json 创建 Dashboard
  1. 下载产生的文件到本地
scp root@<PUBLIC_IP_OF_YOUR_VM>:/srv/copilot-usage-advanced-dashboard/grafana/dashboard-model-*.json .
dashboard-model-2024-12-17.json                                                                                                                                                  100%  157KB 243.8KB/s   00:00
dashboard-model-data_sources_name_uid_mapping-2024-12-17.json                                                                                                                    100%  210     1.1KB/s   00:00
  1. 复制产生的 json 文件,导入到 Grafana
    在这里插入图片描述
    选择文件导入,或者直接粘贴内容
    在这里插入图片描述
  2. Import
    在这里插入图片描述
  3. 恭喜你,此时获得了完整的 Dashboard,但是应该还没有数据。接下来,运行核心程序。

cpuad-updater

是 Copilot Usage Advanced Dashboard Updater 的首字符简写

选项1:✨Docker 方式运行(推荐)

参数说明

  • GITHUB_PAT

    • 你的账户需要具有 Organzations 的 Owner 权限。

    • Create a personal access token (classic)在manage_billing:copilot, read:enterprise, read:org 作用域。

    • 如果遇到了 PAT 权限问题,在组织的 Settings-Personal access tokensAllow access via fine-grained personal access tokens

    • 请替换 <YOUR_GITHUB_PAT> 为实际值。

  • ORGANIZATION_SLUGS:希望被监控的所有Organzation的Slug,可以是一个,也可以是以,(英文符号)分割的多个。如果你使用的是 Copilot Standalone,那么此处请使用你的 Standalone Slug,并且以standalone:作为前缀,例如 standalone:YOUR_STANDALONE_SLUG。请替换 <YOUR_ORGANIZATION_SLUGS> 为实际值。例如,如下类型的值都是支持的:

  • myOrg1

  • myOrg1,myOrg2

  • standalone:myStandaloneSlug

  • myOrg1,standalone:myStandaloneSlug

  • LOG_PATH:日志存储位置,不建议修改。如果修改需要同步修改 -v 数据卷映射。

  • EXECUTION_INTERVAL:更新间隔,默认为每1小时更新一次程序。

docker run -itd \
--net=host \
--restart=always \
--name cpuad \
-e GITHUB_PAT="<YOUR_GITHUB_PAT>" \
-e ORGANIZATION_SLUGS="<YOUR_ORGANIZATION_SLUGS>" \
-e LOG_PATH="logs" \
-e EXECUTION_INTERVAL=1 \
-e ELASTICSEARCH_URL="http://localhost:9200" \
-v /srv/cpuad-updater-logs:/app/logs \
satomic/cpuad-updater
选项2:源码运行
  1. 确认当前在正确的路径中
cd /srv/copilot-usage-advanced-dashboard
  1. 安装依赖
python3 -m pip install -r requirements.txt
  1. 设置环境变量。如果你使用的是 Copilot Standalone,那么此处请使用你的 Standalone Slug,并且以 standalone: 作为前缀,例如 standalone:YOUR_STANDALONE_SLUG
export GITHUB_PAT="<YOUR_GITHUB_PAT>"
export ORGANIZATION_SLUGS="<YOUR_ORGANIZATION_SLUGS>"
  1. 执行
python3 main.py
  1. 输出日志
2024-12-17 05:32:22,292 - [INFO] - Data saved to logs/2024-12-17/nekoaru_level3-team1_copilot_usage_2024-12-17.json
2024-12-17 05:32:22,292 - [INFO] - Fetched Copilot usage for team: level3-team1
2024-12-17 05:32:22,293 - [INFO] - Data saved to logs/2024-12-17/nekoaru_all_teams_copilot_usage_2024-12-17.json
2024-12-17 05:32:22,293 - [INFO] - Processing Copilot usage data for organization: nekoaru
2024-12-17 05:32:22,293 - [INFO] - Processing Copilot usage data for team: level1-team1
2024-12-17 05:32:22,293 - [WARNING] - No Copilot usage data found for team: level1-team1
2024-12-17 05:32:22,293 - [INFO] - Processing Copilot usage data for team: level2-team1
2024-12-17 05:32:22,293 - [WARNING] - No Copilot usage data found for team: level2-team1
2024-12-17 05:32:22,293 - [INFO] - Processing Copilot usage data for team: level2-team2
2024-12-17 05:32:22,293 - [WARNING] - No Copilot usage data found for team: level2-team2
2024-12-17 05:32:22,293 - [INFO] - Processing Copilot usage data for team: level3-team1
2024-12-17 05:32:22,293 - [WARNING] - No Copilot usage data found for team: level3-team1
2024-12-17 05:32:22,293 - [INFO] - Sleeping for 6 hours before next execution...
2024-12-17 05:32:22,293 - [INFO] - Heartbeat: still running...

恭喜完成🎉

当前 VM 中的应用运行状态

此时此刻,在 VM 中,你应该能看到3个容器处于运行中(如果你都是基于 docker 从0开始部署的话),如下:

docker ps
CONTAINER ID   IMAGE                                                  COMMAND                  CREATED        STATUS        PORTS                                                 NAMES
1edffd12a522   satomic/cpuad-updater:20241221                         "python3 main.py"        23 hours ago   Up 10 hours                                                         cpuad
b19e467d48f1   grafana/grafana:11.4.0                                 "/run.sh"                25 hours ago   Up 10 hours                                                         grafana
ee35b2a340f1   docker.elastic.co/elasticsearch/elasticsearch:8.17.0   "/bin/tini -- /usr/l…"   3 days ago     Up 10 hours   0.0.0.0:9200->9200/tcp, :::9200->9200/tcp, 9300/tcp   es

查看 Dashboard

此时,回到 Grafana 页面,刷新,此时,应该可以看到数据了。在这里插入图片描述
或者
在这里插入图片描述
acceptances_count

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐