{"id":622,"date":"2025-02-21T02:44:16","date_gmt":"2025-02-21T02:44:16","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/all-things-azure\/?p=622"},"modified":"2025-02-21T02:44:16","modified_gmt":"2025-02-21T02:44:16","slug":"visualize-roi-of-your-github-copilot-usage-deploy-it","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/all-things-azure\/visualize-roi-of-your-github-copilot-usage-deploy-it\/","title":{"rendered":"Visualize ROI of your GitHub Copilot Usage, Deploy it!"},"content":{"rendered":"<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-content\/uploads\/sites\/83\/2024\/10\/HC0400_MS_AzureDeveloperBlogSeries-Banner_103124_DC_V2-02-2.png\" alt=\"Image HC0400 MS AzureDeveloperBlogSeries Banner 103124 DC V2 02 2\" \/><\/p>\n<div dir=\"auto\"><div class=\"alert alert-success\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Lightbulb\"><\/i><strong>Tips<\/strong><\/p>In today&#8217;s enterprise software development landscape, organizations are increasingly investing in AI-powered development tools like GitHub Copilot to boost developer productivity. However, the standard 28-day usage metrics often fall short of providing the comprehensive insights needed to truly understand ROI and adoption patterns across large organizations. The Copilot Usage Advanced Dashboard fills this critical gap by offering a powerful, enterprise-grade solution that captures and analyzes long-term usage data across multiple teams and organizations. Built with familiar tools like Elasticsearch and Grafana, this dashboard enables engineering leaders to track adoption trends, identify optimization opportunities, and quantify their Copilot investment&#8217;s impact through detailed breakdowns by language, editor, and team. Beyond just tracking lines of code, the dashboard provides insights into seat utilization, activation rates, and usage patterns that help organizations optimize their Copilot licenses and drive stronger developer adoption. For engineering teams evaluating or scaling their Copilot implementation, this tool provides the data-driven insights needed to make informed decisions about resource allocation and demonstrate clear business value to stakeholders.<\/div><\/div>\n<div dir=\"auto\"><\/div>\n<div dir=\"auto\"><\/div>\n<div dir=\"auto\">\n<hr \/>\n<\/div>\n<div dir=\"auto\"><\/div>\n<div dir=\"auto\"><\/div>\n<div dir=\"auto\"><\/div>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h2 class=\"heading-element\" dir=\"auto\" tabindex=\"-1\"><span style=\"font-size: 24pt;\">Deployment: Let&#8217;s do it!<\/span><\/h2>\n<\/div>\n<blockquote>\n<p dir=\"auto\">All operations are performed in the VM<\/p>\n<\/blockquote>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h2 class=\"heading-element\" dir=\"auto\" tabindex=\"-1\">Prerequisites<\/h2>\n<\/div>\n<blockquote>\n<p dir=\"auto\">everything is on-premises and free (except VM)<\/p>\n<\/blockquote>\n<p dir=\"auto\">The only thing you need is:<\/p>\n<ul dir=\"auto\">\n<li>a VM\n<ul dir=\"auto\">\n<li>Memory: 16G is recommended<\/li>\n<li>Operating system: Ubuntu 22.04 (recommended, other operating systems have no difference except Docker installation)<\/li>\n<li>Port:\u00a0<code>3000<\/code>\u00a0port needs to be released for Grafana to use, and\u00a0<code>22<\/code>\u00a0port can be determined by yourself.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p dir=\"auto\">Everything else is based on existing stuff, or based on open source software, no extra cost, for example:<\/p>\n<ul dir=\"auto\">\n<li>GitHub Organzations with Copilot enabled (I believe, you already have it, more to <a href=\"https:\/\/azure.microsoft.com\/en-us\/products\/github\/Copilot\">GitHub Copilot | Microsoft Azure<\/a> or learn from <a href=\"https:\/\/devblogs.microsoft.com\/all-things-azure\/how-to-subscribe-for-github-copilot-business-without-github-enterprise\/\">How to subscribe for GitHub Copilot Business without GitHub Enterprise: A Step-by-Step Guide | All things Azure<\/a>)<\/li>\n<li>Docker (Community Version is enough)<\/li>\n<li>Elasticsearch (Community Version is enough)<\/li>\n<li>Grafana (Community Version is enough, do not need Grafana Cloud Account)<\/li>\n<li>CPUAD-Updater build from this project (MIT license)<\/li>\n<\/ul>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h2 class=\"heading-element\" dir=\"auto\" tabindex=\"-1\">Docker<\/h2>\n<\/div>\n<p dir=\"auto\">For installation instructions, refer to\u00a0<a title=\"Install Docker Engine\" href=\"https:\/\/docs.docker.com\/engine\/install\/\" rel=\"nofollow\">Install Docker Engine<\/a>. For Ubuntu 22.04, you can use the following command<\/p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\">\n<pre>apt install docker.io<\/pre>\n<div class=\"zeroclipboard-container\"><\/div>\n<\/div>\n<p dir=\"auto\">verify<\/p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\">\n<pre>docker version<\/pre>\n<div class=\"zeroclipboard-container\"><\/div>\n<\/div>\n<p dir=\"auto\">The following content is obtained, indicating ok<\/p>\n<div class=\"highlight highlight-text-md notranslate position-relative overflow-auto\" dir=\"auto\">\n<pre>Client:\r\n Version:           24.0.7\r\n API version:       1.43\r\n Go version:        go1.21.1\r\n Git commit:        24.0.7-0ubuntu2<span class=\"pl-s\">~<\/span>22.04.1\r\n Built:             Wed Mar 13 20:23:54 2024\r\n OS\/Arch:           linux\/amd64\r\n Context:           default\r\n\r\nServer:\r\n Engine:\r\n  Version:          24.0.7\r\n  API version:      1.43 (minimum version 1.12)\r\n  Go version:       go1.21.1\r\n  Git commit:       24.0.7-0ubuntu2<span class=\"pl-s\">~<\/span>22.04.1\r\n  Built:            Wed Mar 13 20:23:54 2024\r\n  OS\/Arch:          linux\/amd64\r\n  Experimental:     false\r\n containerd:\r\n  Version:          1.7.12\r\n  GitCommit:\r\n runc:\r\n  Version:          1.1.12-0ubuntu2<span class=\"pl-s\">~<\/span>22.04.1\r\n  GitCommit:\r\n docker-init:\r\n  Version:          0.19.0\r\n  GitCommit:\r\n<\/pre>\n<\/div>\n<div class=\"zeroclipboard-container\"><\/div>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h2 class=\"heading-element\" dir=\"auto\" tabindex=\"-1\">Download source code<\/h2>\n<\/div>\n<p dir=\"auto\">Put all the work in the\u00a0<code>\/srv<\/code>\u00a0directory, click\u00a0<a title=\"download zip archive\" href=\"https:\/\/github.com\/satomic\/copilot-usage-advanced-dashboard\/archive\/refs\/heads\/main.zip\">download zip archive<\/a>, unzip and rename the folder to\u00a0<code>copilot-usage-advanced-dashboard<\/code>, or directly\u00a0<code>git clone<\/code><\/p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\">\n<pre><span class=\"pl-c1\">cd<\/span> \/srv\r\ngit clone https:\/\/github.com\/satomic\/copilot-usage-advanced-dashboard.git\r\n<span class=\"pl-c1\">cd<\/span> copilot-usage-advanced-dashboard\r\n<\/pre>\n<div class=\"zeroclipboard-container\"><\/div>\n<\/div>\n<p dir=\"auto\">verify<\/p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\">\n<pre>ls -ltr<\/pre>\n<div class=\"zeroclipboard-container\"><\/div>\n<\/div>\n<p dir=\"auto\">The following content is obtained, indicating ok<\/p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\">\n<pre>total 64\r\n-rw-r--r-- 1 root root   100 Dec 16 11:22 fetch.sh\r\n-rw-r--r-- 1 root root    56 Dec 16 11:22 docker_build.sh\r\n-rw-r--r-- 1 root root  1063 Dec 16 11:22 LICENSE\r\n-rw-r--r-- 1 root root  1031 Dec 16 11:22 Dockerfile\r\n-rw-r--r-- 1 root root   193 Dec 16 11:22 push.sh\r\ndrwxr-xr-x 2 root root  4096 Dec 16 11:22 mapping\r\n-rw-r--r-- 1 root root    22 Dec 16 11:32 requirements.txt\r\n-rw-r--r-- 1 root root   996 Dec 16 13:44 log_utils.py\r\ndrwxr-xr-x 2 root root  4096 Dec 17 00:18 grafana\r\n-rw-r--r-- 1 root root  2571 Dec 17 00:18 gen_grafana_model.py\r\n-rw-r--r-- 1 root root 22500 Dec 17 01:40 main.py\r\n<\/pre>\n<div class=\"zeroclipboard-container\"><\/div>\n<\/div>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h2 class=\"heading-element\" dir=\"auto\" tabindex=\"-1\">Elasticsearch<\/h2>\n<\/div>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h3 class=\"heading-element\" dir=\"auto\" tabindex=\"-1\">Installation<\/h3>\n<\/div>\n<blockquote>\n<p dir=\"auto\">If you already have ES, you can skip this step and go directly to the next step.<\/p>\n<\/blockquote>\n<blockquote>\n<p dir=\"auto\">ES will not be exposed to the outside of the VM, so there is no need to enable\u00a0<code>xpack.security.enabled<\/code><\/p>\n<\/blockquote>\n<ol dir=\"auto\">\n<li>Create a data persistence directory and a configuration file directory for Elasticsearch:\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\">\n<pre>mkdir -p \/srv\/elasticsearch\/data \/srv\/elasticsearch\/config<\/pre>\n<div class=\"zeroclipboard-container\"><\/div>\n<\/div>\n<\/li>\n<li>Grant read and write permissions.\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\">\n<pre>chown -R 777 \/srv\/elasticsearch\/<\/pre>\n<div class=\"zeroclipboard-container\"><\/div>\n<\/div>\n<\/li>\n<li>Create the\u00a0<code>elasticsearch.yml<\/code>\u00a0configuration file in the\u00a0<code>\/srv\/elasticsearch\/config\/<\/code>directory:\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\">\n<pre>cat <span class=\"pl-k\">&gt;&gt;<\/span> \/srv\/elasticsearch\/config\/elasticsearch.yml <span class=\"pl-s\"><span class=\"pl-k\">&lt;&lt;<\/span> <span class=\"pl-k\">EOF<\/span><\/span>\r\n<span class=\"pl-s\">network.host: 0.0.0.0<\/span>\r\n<span class=\"pl-s\">node.name: single-node<\/span>\r\n<span class=\"pl-s\">cluster.name: es-docker-cluster<\/span>\r\n<span class=\"pl-s\">path.data: \/usr\/share\/elasticsearch\/data<\/span>\r\n<span class=\"pl-s\">path.logs: \/usr\/share\/elasticsearch\/logs<\/span>\r\n<span class=\"pl-s\">discovery.type: single-node<\/span>\r\n<span class=\"pl-s\">bootstrap.memory_lock: true<\/span>\r\n<span class=\"pl-s\"><span class=\"pl-k\">EOF<\/span><\/span><\/pre>\n<div class=\"zeroclipboard-container\"><\/div>\n<\/div>\n<\/li>\n<li>Use the following command to start Elasticsearch and bind the data directory and configuration file:\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\">\n<pre>docker run -itd --restart always --name es \\\r\n  -p 9200:9200 \\\r\n  -e <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>xpack.security.enabled=false<span class=\"pl-pds\">\"<\/span><\/span> \\\r\n  -e <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>ES_JAVA_OPTS=-Xms4g -Xmx4g<span class=\"pl-pds\">\"<\/span><\/span> \\\r\n  -v \/srv\/elasticsearch\/data:\/usr\/share\/elasticsearch\/data \\\r\n  -v \/srv\/elasticsearch\/config\/elasticsearch.yml:\/usr\/share\/elasticsearch\/config\/elasticsearch.yml:ro \\\r\n  docker.elastic.co\/elasticsearch\/elasticsearch:8.17.0\r\n<\/pre>\n<div class=\"zeroclipboard-container\"><\/div>\n<\/div>\n<\/li>\n<li>verify\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\">\n<pre>curl http:\/\/localhost:9200<\/pre>\n<div class=\"zeroclipboard-container\"><\/div>\n<\/div>\n<p>The following content is obtained, indicating ok<\/p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\">\n<pre>{\r\n    <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>name<span class=\"pl-pds\">\"<\/span><\/span>: <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>single-node<span class=\"pl-pds\">\"<\/span><\/span>,\r\n    <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>cluster_name<span class=\"pl-pds\">\"<\/span><\/span>: <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>es-docker-cluster<span class=\"pl-pds\">\"<\/span><\/span>,\r\n    <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>cluster_uuid<span class=\"pl-pds\">\"<\/span><\/span>: <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>oO3mfjYWTZ6VZFSClDiSLA<span class=\"pl-pds\">\"<\/span><\/span>,\r\n    <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>version<span class=\"pl-pds\">\"<\/span><\/span>: {\r\n        <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>number<span class=\"pl-pds\">\"<\/span><\/span>: <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>8.17.0<span class=\"pl-pds\">\"<\/span><\/span>,\r\n        <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>build_flavor<span class=\"pl-pds\">\"<\/span><\/span>: <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>default<span class=\"pl-pds\">\"<\/span><\/span>,\r\n        <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>build_type<span class=\"pl-pds\">\"<\/span><\/span>: <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>docker<span class=\"pl-pds\">\"<\/span><\/span>,\r\n        <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>build_hash<span class=\"pl-pds\">\"<\/span><\/span>: <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>2b6a7fed44faa321997703718f07ee0420804b41<span class=\"pl-pds\">\"<\/span><\/span>,\r\n        <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>build_date<span class=\"pl-pds\">\"<\/span><\/span>: <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>2024-12-11T12:08:05.663969764Z<span class=\"pl-pds\">\"<\/span><\/span>,\r\n        <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>build_snapshot<span class=\"pl-pds\">\"<\/span><\/span>: false,\r\n        <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>lucene_version<span class=\"pl-pds\">\"<\/span><\/span>: <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>9.12.0<span class=\"pl-pds\">\"<\/span><\/span>,\r\n        <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>minimum_wire_compatibility_version<span class=\"pl-pds\">\"<\/span><\/span>: <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>7.17.0<span class=\"pl-pds\">\"<\/span><\/span>,\r\n        <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>minimum_index_compatibility_version<span class=\"pl-pds\">\"<\/span><\/span>: <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>7.0.0<span class=\"pl-pds\">\"<\/span><\/span>\r\n    },\r\n    <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>tagline<span class=\"pl-pds\">\"<\/span><\/span>: <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>You Know, for Search<span class=\"pl-pds\">\"<\/span><\/span>\r\n}<\/pre>\n<div class=\"zeroclipboard-container\"><\/div>\n<\/div>\n<\/li>\n<\/ol>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h3 class=\"heading-element\" dir=\"auto\" tabindex=\"-1\">Create index<\/h3>\n<\/div>\n<ol dir=\"auto\">\n<li>Confirm that you are in the correct path\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\">\n<pre><span class=\"pl-c1\">cd<\/span> \/srv\/copilot-usage-advanced-dashboard<\/pre>\n<div class=\"zeroclipboard-container\"><\/div>\n<\/div>\n<\/li>\n<li>Execute the script and create an index\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\">\n<pre>bash create_es_indexes.sh<\/pre>\n<div class=\"zeroclipboard-container\"><\/div>\n<\/div>\n<p>The following content is obtained, indicating ok<\/p>\n<div class=\"highlight highlight-source-json notranslate position-relative overflow-auto\" dir=\"auto\">\n<pre>{<span class=\"pl-ent\">\"acknowledged\"<\/span>:<span class=\"pl-c1\">true<\/span>,<span class=\"pl-ent\">\"shards_acknowledged\"<\/span>:<span class=\"pl-c1\">true<\/span>,<span class=\"pl-ent\">\"index\"<\/span>:<span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>copilot_usage_total<span class=\"pl-pds\">\"<\/span><\/span>}\r\n{<span class=\"pl-ent\">\"acknowledged\"<\/span>:<span class=\"pl-c1\">true<\/span>,<span class=\"pl-ent\">\"shards_acknowledged\"<\/span>:<span class=\"pl-c1\">true<\/span>,<span class=\"pl-ent\">\"index\"<\/span>:<span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>copilot_usage_breakdown<span class=\"pl-pds\">\"<\/span><\/span>}\r\n{<span class=\"pl-ent\">\"acknowledged\"<\/span>:<span class=\"pl-c1\">true<\/span>,<span class=\"pl-ent\">\"shards_acknowledged\"<\/span>:<span class=\"pl-c1\">true<\/span>,<span class=\"pl-ent\">\"index\"<\/span>:<span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>copilot_seat_info_settings<span class=\"pl-pds\">\"<\/span><\/span>}\r\n{<span class=\"pl-ent\">\"acknowledged\"<\/span>:<span class=\"pl-c1\">true<\/span>,<span class=\"pl-ent\">\"shards_acknowledged\"<\/span>:<span class=\"pl-c1\">true<\/span>,<span class=\"pl-ent\">\"index\"<\/span>:<span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>copilot_seat_assignments<span class=\"pl-pds\">\"<\/span><\/span>}<\/pre>\n<div class=\"zeroclipboard-container\"><\/div>\n<\/div>\n<\/li>\n<li>verify\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\">\n<pre>curl -X GET http:\/\/localhost:9200\/_cat\/indices<span class=\"pl-k\">?<\/span>v<\/pre>\n<div class=\"zeroclipboard-container\"><\/div>\n<\/div>\n<p>The following content is obtained, indicating ok<\/p>\n<div class=\"highlight highlight-text-md notranslate position-relative overflow-auto\" dir=\"auto\">\n<pre>health status index                      uuid                   pri rep docs.count docs.deleted store.size pri.store.size dataset.size\r\nyellow open   copilot_usage_total        XrOEfAngTS60VsuUz3Lbrw   1   1          0            0       227b           227b         227b\r\nyellow open   copilot_seat_info_settings WtOBdBNUQRqua7wi7VANeQ   1   1          0            0       227b           227b         227b\r\nyellow open   copilot_seat_assignments   lK5t4SwASZizPQ_W4NX4KQ   1   1          0            0       227b           227b         227b\r\nyellow open   copilot_usage_breakdown    xE6tkg5GQEOP-EP8pwAkYg   1   1          0            0       227b           227b         227b\r\n<\/pre>\n<div class=\"zeroclipboard-container\"><\/div>\n<\/div>\n<\/li>\n<\/ol>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h2 class=\"heading-element\" dir=\"auto\" tabindex=\"-1\">Grafana<\/h2>\n<\/div>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h3 class=\"heading-element\" dir=\"auto\" tabindex=\"-1\">Installation<\/h3>\n<\/div>\n<blockquote>\n<p dir=\"auto\">If you already have Grafana, you can skip this step and go directly to the next step.<\/p>\n<\/blockquote>\n<ol dir=\"auto\">\n<li>Creating a Data Path\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\">\n<pre>mkdir -p \/srv\/grafana\/data\r\nchmod 777 \/srv\/grafana\/data<\/pre>\n<div class=\"zeroclipboard-container\"><\/div>\n<\/div>\n<\/li>\n<li>run\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\">\n<pre>docker run  -itd --restart always --name=grafana \\\r\n  --net=host \\\r\n  -p 3000:3000 \\\r\n  -v \/srv\/grafana\/data:\/var\/lib\/grafana \\\r\n  -e <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>GF_LOG_LEVEL=debug<span class=\"pl-pds\">\"<\/span><\/span> \\\r\n  grafana\/grafana:11.4.0<\/pre>\n<div class=\"zeroclipboard-container\"><\/div>\n<\/div>\n<\/li>\n<li>Access Grafana\n<ul dir=\"auto\">\n<li>Access address:\u00a0<code>http:\/\/&lt;PUBLIC_IP_OF_YOUR_VM&gt;:3000<\/code><\/li>\n<li>The default username and password are\u00a0<code>admin<\/code>\/\u00a0<code>admin<\/code>, please change the password<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h3 dir=\"auto\" tabindex=\"-1\"><\/h3>\n<h3 class=\"heading-element\" dir=\"auto\" tabindex=\"-1\">Create Admin Token<\/h3>\n<\/div>\n<ol dir=\"auto\">\n<li>\n<p dir=\"auto\">admin visit\u00a0<strong>Administration<\/strong>\u00a0\u2192\u00a0<strong>Users and access<\/strong>\u00a0\u2192\u00a0<strong>Service accounts<\/strong><\/p>\n<p dir=\"auto\"><a href=\"https:\/\/github.com\/satomic\/copilot-usage-advanced-dashboard\/blob\/main\/image\/image_KY8b0hv5g1.png\" target=\"_blank\" rel=\"noopener noreferrer\"><img decoding=\"async\" class=\"alignnone\" src=\"https:\/\/github.com\/satomic\/copilot-usage-advanced-dashboard\/raw\/main\/image\/image_KY8b0hv5g1.png\" alt=\"Create Admin Token Service accounts\" width=\"1293\" height=\"750\" \/><\/a><\/p>\n<\/li>\n<li>\n<p dir=\"auto\">input\u00a0<strong>Display name<\/strong>\uff0c<strong>Role<\/strong>\u00a0select\u00a0<code>Admin<\/code>,\u00a0<strong>Create<\/strong><\/p>\n<p dir=\"auto\"><a href=\"https:\/\/github.com\/satomic\/copilot-usage-advanced-dashboard\/blob\/main\/image\/image_wjIjr2vLYJ.png\" target=\"_blank\" rel=\"noopener noreferrer\"><img decoding=\"async\" class=\"alignnone\" src=\"https:\/\/github.com\/satomic\/copilot-usage-advanced-dashboard\/raw\/main\/image\/image_wjIjr2vLYJ.png\" alt=\"create service account\" width=\"1293\" height=\"750\" \/><\/a><\/p>\n<\/li>\n<li>\n<p dir=\"auto\">click\u00a0<strong>Add service account token<\/strong><\/p>\n<p dir=\"auto\"><a href=\"https:\/\/github.com\/satomic\/copilot-usage-advanced-dashboard\/blob\/main\/image\/image_tXLYRaldHa.png\" target=\"_blank\" rel=\"noopener noreferrer\"><img decoding=\"async\" class=\"alignnone\" src=\"https:\/\/github.com\/satomic\/copilot-usage-advanced-dashboard\/raw\/main\/image\/image_tXLYRaldHa.png\" alt=\"Add service account token\" width=\"1293\" height=\"750\" \/><\/a><\/p>\n<\/li>\n<li>\n<p dir=\"auto\">click\u00a0<strong>Generate token<\/strong><\/p>\n<p dir=\"auto\"><a href=\"https:\/\/github.com\/satomic\/copilot-usage-advanced-dashboard\/blob\/main\/image\/image_B1twE5g-hS.png\" target=\"_blank\" rel=\"noopener noreferrer\"><img decoding=\"async\" class=\"alignnone\" src=\"https:\/\/github.com\/satomic\/copilot-usage-advanced-dashboard\/raw\/main\/image\/image_B1twE5g-hS.png\" alt=\"\u00a0Generate token\" width=\"1293\" height=\"750\" \/><\/a><\/p>\n<\/li>\n<li>\n<p dir=\"auto\"><strong>Copy to clipboard and close<\/strong><\/p>\n<p dir=\"auto\"><a href=\"https:\/\/github.com\/satomic\/copilot-usage-advanced-dashboard\/blob\/main\/image\/image_Ahoe1eqPzS.png\" target=\"_blank\" rel=\"noopener noreferrer\"><img decoding=\"async\" class=\"alignnone\" src=\"https:\/\/github.com\/satomic\/copilot-usage-advanced-dashboard\/raw\/main\/image\/image_Ahoe1eqPzS.png\" alt=\"Copy to clipboard and close\" width=\"1293\" height=\"750\" \/><\/a><\/p>\n<\/li>\n<li>\n<p dir=\"auto\">Now, you have obtained your Grafana Token\u00a0<code>\"&lt;your_grafana_token&gt;\"<\/code>, please save it and set it as an environment variable in the VM, which will be used in the next steps.<\/p>\n<div class=\"highlight highlight-source-js notranslate position-relative overflow-auto\" dir=\"auto\">\n<pre><span class=\"pl-k\">export<\/span> <span class=\"pl-c1\">GRAFANA_TOKEN<\/span><span class=\"pl-c1\">=<\/span><span class=\"pl-s\">\"&lt;your_grafana_token&gt;\"<\/span><\/pre>\n<div class=\"zeroclipboard-container\"><\/div>\n<\/div>\n<\/li>\n<\/ol>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h3 class=\"heading-element\" dir=\"auto\" tabindex=\"-1\">Adding Data sources via API<\/h3>\n<\/div>\n<ol dir=\"auto\">\n<li>\n<p dir=\"auto\">Confirm that you are in the correct path<\/p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\">\n<pre><span class=\"pl-c1\">cd<\/span> \/srv\/copilot-usage-advanced-dashboard<\/pre>\n<div class=\"zeroclipboard-container\"><\/div>\n<\/div>\n<\/li>\n<li>\n<p dir=\"auto\">run script, add data sources<\/p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\">\n<pre>bash add_grafana_data_sources.sh<\/pre>\n<div class=\"zeroclipboard-container\"><\/div>\n<\/div>\n<\/li>\n<li>\n<p dir=\"auto\">Visit the Grafana UI to confirm that the addition was successful<\/p>\n<p dir=\"auto\"><a href=\"https:\/\/github.com\/satomic\/copilot-usage-advanced-dashboard\/blob\/main\/image\/image_Rz9qwfv9X2.png\" target=\"_blank\" rel=\"noopener noreferrer\"><img decoding=\"async\" class=\"alignnone\" src=\"https:\/\/github.com\/satomic\/copilot-usage-advanced-dashboard\/raw\/main\/image\/image_Rz9qwfv9X2.png\" alt=\"confirm that the addition was successful\" width=\"1293\" height=\"750\" \/><\/a><\/p>\n<\/li>\n<\/ol>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h3 dir=\"auto\" tabindex=\"-1\"><\/h3>\n<h3 class=\"heading-element\" dir=\"auto\" tabindex=\"-1\">Generate Dashboard Json Model<\/h3>\n<\/div>\n<ol dir=\"auto\">\n<li>Confirm that you are in the correct path\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\">\n<pre><span class=\"pl-c1\">cd<\/span> \/srv\/copilot-usage-advanced-dashboard<\/pre>\n<div class=\"zeroclipboard-container\"><\/div>\n<\/div>\n<\/li>\n<li>Execute the script to generate a Grafana json model. Execute one of the following two commands\n<div class=\"highlight highlight-source-python notranslate position-relative overflow-auto\" dir=\"auto\">\n<pre><span class=\"pl-c\"># Generate Copilot Usage Advanced Dashboard<\/span>\r\n<span class=\"pl-s1\">python3<\/span> <span class=\"pl-s1\">gen_grafana_model<\/span>.<span class=\"pl-c1\">py<\/span> <span class=\"pl-c1\">-<\/span><span class=\"pl-c1\">-<\/span><span class=\"pl-s1\">template<\/span><span class=\"pl-c1\">=<\/span><span class=\"pl-s1\">grafana<\/span><span class=\"pl-c1\">\/<\/span><span class=\"pl-s1\">dashboard<\/span><span class=\"pl-c1\">-<\/span><span class=\"pl-s1\">template<\/span>.<span class=\"pl-c1\">json<\/span>\r\n\r\n<span class=\"pl-c\"># Generate Copilot Usage Advanced Dashboard Original<\/span>\r\n<span class=\"pl-s1\">python3<\/span> <span class=\"pl-s1\">gen_grafana_model<\/span>.<span class=\"pl-c1\">py<\/span> <span class=\"pl-c1\">-<\/span><span class=\"pl-c1\">-<\/span><span class=\"pl-s1\">template<\/span><span class=\"pl-c1\">=<\/span><span class=\"pl-s1\">grafana<\/span><span class=\"pl-c1\">\/<\/span><span class=\"pl-s1\">dashboard<\/span><span class=\"pl-c1\">-<\/span><span class=\"pl-s1\">template<\/span><span class=\"pl-c1\">-<\/span><span class=\"pl-s1\">original<\/span>.<span class=\"pl-c1\">json<\/span><\/pre>\n<div class=\"zeroclipboard-container\"><\/div>\n<\/div>\n<p>Get the output<\/p>\n<div class=\"highlight highlight-text-md notranslate position-relative overflow-auto\" dir=\"auto\">\n<pre>Model saved to grafana\/dashboard-model-2024-12-17.json, please import it to Grafana<\/pre>\n<div class=\"zeroclipboard-container\"><\/div>\n<\/div>\n<\/li>\n<\/ol>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h3 class=\"heading-element\" dir=\"auto\" tabindex=\"-1\">Import the generated Json to create a Dashboard<\/h3>\n<\/div>\n<ol dir=\"auto\">\n<li>\n<p dir=\"auto\">Download the generated file to your local computer<\/p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\">\n<pre>scp root@<span class=\"pl-k\">&lt;<\/span>PUBLIC_IP_OF_YOUR_VM<span class=\"pl-k\">&gt;<\/span>:\/srv\/copilot-usage-advanced-dashboard\/grafana\/dashboard-model-<span class=\"pl-k\">*<\/span>.json <span class=\"pl-c1\">.<\/span>\r\ndashboard-model-2024-12-17.json                                                                                                                                                  100%  157KB 243.8KB\/s   00:00\r\ndashboard-model-data_sources_name_uid_mapping-2024-12-17.json                                                                                                                    100%  210     1.1KB\/s   00:00<\/pre>\n<div class=\"zeroclipboard-container\"><\/div>\n<\/div>\n<\/li>\n<li>\n<p dir=\"auto\">Copy the generated json file and import it into Grafana<\/p>\n<p dir=\"auto\"><a href=\"https:\/\/github.com\/satomic\/copilot-usage-advanced-dashboard\/blob\/main\/image\/image_AYrtVirvr1.png\" target=\"_blank\" rel=\"noopener noreferrer\"><img decoding=\"async\" class=\"alignnone\" src=\"https:\/\/github.com\/satomic\/copilot-usage-advanced-dashboard\/raw\/main\/image\/image_AYrtVirvr1.png\" alt=\"copy the generated json file and import it into Grafana\" width=\"1293\" height=\"750\" \/><\/a><\/p>\n<p dir=\"auto\">Select the file to import, or paste the content directly<\/p>\n<p dir=\"auto\"><a href=\"https:\/\/github.com\/satomic\/copilot-usage-advanced-dashboard\/blob\/main\/image\/image_w_wlgST2uO.png\" target=\"_blank\" rel=\"noopener noreferrer\"><img decoding=\"async\" class=\"alignnone\" src=\"https:\/\/github.com\/satomic\/copilot-usage-advanced-dashboard\/raw\/main\/image\/image_w_wlgST2uO.png\" alt=\"import, or paste the content directly\" width=\"1293\" height=\"750\" \/><\/a><\/p>\n<\/li>\n<li>\n<p dir=\"auto\"><strong>Import<\/strong><\/p>\n<p dir=\"auto\"><a href=\"https:\/\/github.com\/satomic\/copilot-usage-advanced-dashboard\/blob\/main\/image\/image_ojvK2wCe7i.png\" target=\"_blank\" rel=\"noopener noreferrer\"><img decoding=\"async\" class=\"alignnone\" src=\"https:\/\/github.com\/satomic\/copilot-usage-advanced-dashboard\/raw\/main\/image\/image_ojvK2wCe7i.png\" alt=\"Import\" width=\"1293\" height=\"750\" \/><\/a><\/p>\n<\/li>\n<li>\n<p dir=\"auto\">Congratulations, you now have a complete dashboard, but there should be no data yet. Next, run the core program.<\/p>\n<\/li>\n<\/ol>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h2 dir=\"auto\" tabindex=\"-1\"><\/h2>\n<h2 class=\"heading-element\" dir=\"auto\" tabindex=\"-1\">cpuad-updater<\/h2>\n<\/div>\n<blockquote>\n<p dir=\"auto\">is the abbreviation of the first characters of\u00a0<strong>Copilot Usage Advanced Dashboard Updater<\/strong><\/p>\n<\/blockquote>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h3 dir=\"auto\" tabindex=\"-1\"><\/h3>\n<h3 class=\"heading-element\" dir=\"auto\" tabindex=\"-1\">Option 1. Run in docker mode (recommended)<\/h3>\n<\/div>\n<p dir=\"auto\">Parameter description<\/p>\n<ul dir=\"auto\">\n<li><code>GITHUB_PAT<\/code>: Your GitHub PAT, which needs to have Owner permissions for Organizations. Please replace\u00a0<code>&lt;YOUR_GITHUB_PAT&gt;<\/code>\u00a0with the actual value.<\/li>\n<li><code>ORGANIZATION_SLUGS<\/code>: The Slugs of all Organizations that you want to monitor, which can be one or multiple separated by\u00a0<code>,<\/code>\u00a0(English symbol). If you are using Copilot Standalone, use your Standalone Slug here, prefixed with <code>standalone:<\/code>, for example <code>standalone:YOUR_STANDALONE_SLUG<\/code>. Please replace <code>&lt;YOUR_ORGANIZATION_SLUGS&gt;<\/code>\u00a0with the actual value. For example, the following types of values are supported:\n<ul dir=\"auto\">\n<li><code>myOrg1<\/code><\/li>\n<li><code>myOrg1,myOrg2<\/code><\/li>\n<li><code>standalone:myStandaloneSlug<\/code><\/li>\n<li><code>myOrg1,standalone:myStandaloneSlug<\/code><\/li>\n<\/ul>\n<\/li>\n<li><code>LOG_PATH<\/code>: Log storage location, not recommended to modify. If modified, you need to modify the\u00a0<code>-v<\/code>\u00a0data volume mapping simultaneously.<\/li>\n<li><code>EXECUTION_INTERVAL<\/code>: Update interval, the default is to update the program every\u00a0<code>1<\/code>\u00a0hours.<\/li>\n<\/ul>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\">\n<pre>docker run -itd \\\r\n--net=host \\\r\n--restart=always \\\r\n--name cpuad \\\r\n-e GITHUB_PAT=<span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>&lt;YOUR_GITHUB_PAT&gt;<span class=\"pl-pds\">\"<\/span><\/span> \\\r\n-e ORGANIZATION_SLUGS=<span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>&lt;YOUR_ORGANIZATION_SLUGS&gt;<span class=\"pl-pds\">\"<\/span><\/span> \\\r\n-e LOG_PATH=<span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>logs<span class=\"pl-pds\">\"<\/span><\/span> \\\r\n-e EXECUTION_INTERVAL=1 \\\r\n-e ELASTICSEARCH_URL=<span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>http:\/\/localhost:9200<span class=\"pl-pds\">\"<\/span><\/span> \\\r\n-v \/srv\/cpuad-updater-logs:\/app\/logs \\\r\nsatomic\/cpuad-updater<\/pre>\n<div class=\"zeroclipboard-container\"><\/div>\n<\/div>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h3 class=\"heading-element\" dir=\"auto\" tabindex=\"-1\">Option 2. Run in source code mode<\/h3>\n<\/div>\n<ol dir=\"auto\">\n<li>Confirm that you are in the correct path\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\">\n<pre><span class=\"pl-c1\">cd<\/span> \/srv\/copilot-usage-advanced-dashboard<\/pre>\n<div class=\"zeroclipboard-container\"><\/div>\n<\/div>\n<\/li>\n<li>Install Dependencies\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\">\n<pre>python3 -m pip install -r requirements.txt<\/pre>\n<div class=\"zeroclipboard-container\"><\/div>\n<\/div>\n<\/li>\n<li>Setting Environment Variables.\u00a0If you are using Copilot Standalone, use your Standalone Slug here, prefixed with <code>standalone:<\/code>, for example <code>standalone:YOUR_STANDALONE_SLUG<\/code>.\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\">\n<pre><span class=\"pl-k\">export<\/span> GITHUB_PAT=<span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>&lt;YOUR_GITHUB_PAT&gt;<span class=\"pl-pds\">\"<\/span><\/span>\r\n<span class=\"pl-k\">export<\/span> ORGANIZATION_SLUGS=<span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>&lt;YOUR_ORGANIZATION_SLUGS&gt;<span class=\"pl-pds\">\"<\/span><\/span>\r\n<\/pre>\n<div class=\"zeroclipboard-container\"><\/div>\n<\/div>\n<\/li>\n<li>run\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\">\n<pre>python3 main.py<\/pre>\n<div class=\"zeroclipboard-container\"><\/div>\n<\/div>\n<\/li>\n<li>output logs\n<div class=\"snippet-clipboard-content notranslate position-relative overflow-auto\">\n<pre class=\"notranslate\" lang=\"text\"><code>2024-12-17 05:32:22,292 - [INFO] - Data saved to logs\/2024-12-17\/nekoaru_level3-team1_copilot_usage_2024-12-17.json\r\n2024-12-17 05:32:22,292 - [INFO] - Fetched Copilot usage for team: level3-team1\r\n2024-12-17 05:32:22,293 - [INFO] - Data saved to logs\/2024-12-17\/nekoaru_all_teams_copilot_usage_2024-12-17.json\r\n2024-12-17 05:32:22,293 - [INFO] - Processing Copilot usage data for organization: nekoaru\r\n2024-12-17 05:32:22,293 - [INFO] - Processing Copilot usage data for team: level1-team1\r\n2024-12-17 05:32:22,293 - [WARNING] - No Copilot usage data found for team: level1-team1\r\n2024-12-17 05:32:22,293 - [INFO] - Processing Copilot usage data for team: level2-team1\r\n2024-12-17 05:32:22,293 - [WARNING] - No Copilot usage data found for team: level2-team1\r\n2024-12-17 05:32:22,293 - [INFO] - Processing Copilot usage data for team: level2-team2\r\n2024-12-17 05:32:22,293 - [WARNING] - No Copilot usage data found for team: level2-team2\r\n2024-12-17 05:32:22,293 - [INFO] - Processing Copilot usage data for team: level3-team1\r\n2024-12-17 05:32:22,293 - [WARNING] - No Copilot usage data found for team: level3-team1\r\n2024-12-17 05:32:22,293 - [INFO] - Sleeping for 6 hours before next execution...\r\n2024-12-17 05:32:22,293 - [INFO] - Heartbeat: still running...\r\n\r\n<\/code><\/pre>\n<div class=\"zeroclipboard-container\"><\/div>\n<\/div>\n<\/li>\n<\/ol>\n<hr \/>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h2 class=\"heading-element\" dir=\"auto\" tabindex=\"-1\"><span style=\"font-size: 24pt;\">Congratulations<\/span><\/h2>\n<\/div>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h2 class=\"heading-element\" dir=\"auto\" tabindex=\"-1\">Current application running status in the VM<\/h2>\n<\/div>\n<p dir=\"auto\">At this moment, in the VM, you should be able to see 3 containers running (if you have deployed them from scratch based on docker), as follows:<\/p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\">\n<pre>docker ps\r\n\r\nCONTAINER ID   IMAGE                                                  COMMAND                  CREATED        STATUS        PORTS                                                 NAMES\r\n1edffd12a522   satomic\/cpuad-updater:20241221                         <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>python3 main.py<span class=\"pl-pds\">\"<\/span><\/span>        23 hours ago   Up 10 hours                                                         cpuad\r\nb19e467d48f1   grafana\/grafana:11.4.0                                 <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>\/run.sh<span class=\"pl-pds\">\"<\/span><\/span>                25 hours ago   Up 10 hours                                                         grafana\r\nee35b2a340f1   docker.elastic.co\/elasticsearch\/elasticsearch:8.17.0   <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>\/bin\/tini -- \/usr\/l\u2026<span class=\"pl-pds\">\"<\/span><\/span>   3 days ago     Up 10 hours   0.0.0.0:9200-<span class=\"pl-k\">&gt;<\/span>9200\/tcp, :::9200-<span class=\"pl-k\">&gt;<\/span>9200\/tcp, 9300\/tcp   es<\/pre>\n<div class=\"zeroclipboard-container\"><\/div>\n<\/div>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h2 class=\"heading-element\" dir=\"auto\" tabindex=\"-1\">View Dashboard<\/h2>\n<\/div>\n<p dir=\"auto\">At this point, return to the Grafana page and refresh. You should be able to see the data.<\/p>\n<p dir=\"auto\"><a href=\"https:\/\/github.com\/satomic\/copilot-usage-advanced-dashboard\/blob\/main\/image\/image_lf08iyNeUt.png\" target=\"_blank\" rel=\"noopener noreferrer\"><img decoding=\"async\" class=\"alignnone\" src=\"https:\/\/github.com\/satomic\/copilot-usage-advanced-dashboard\/raw\/main\/image\/image_lf08iyNeUt.png\" alt=\"View Dashboard\" width=\"2220\" height=\"1264\" \/><\/a><\/p>\n<p dir=\"auto\">or<\/p>\n<p dir=\"auto\"><a href=\"https:\/\/github.com\/satomic\/copilot-usage-advanced-dashboard\/blob\/main\/image\/image_wjdhYnlwOZ.png\" target=\"_blank\" rel=\"noopener noreferrer\"><img decoding=\"async\" class=\"alignnone\" src=\"https:\/\/github.com\/satomic\/copilot-usage-advanced-dashboard\/raw\/main\/image\/image_wjdhYnlwOZ.png\" alt=\"View Dashboard 2\" width=\"2552\" height=\"1280\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Deployment: Let&#8217;s do it! All operations are performed in the VM Prerequisites everything is on-premises and free (except VM) The only thing you need is: a VM Memory: 16G is recommended Operating system: Ubuntu 22.04 (recommended, other operating systems have no difference except Docker installation) Port:\u00a03000\u00a0port needs to be released for Grafana to use, and\u00a022\u00a0port [&hellip;]<\/p>\n","protected":false},"author":174024,"featured_media":12,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1,20,19],"tags":[28,48,21,47,49],"class_list":["post-622","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-azure","category-developer-productivity","category-github-copilot","tag-copilot","tag-dashboard","tag-github","tag-metrics","tag-visualization"],"acf":[],"blog_post_summary":"<p>Deployment: Let&#8217;s do it! All operations are performed in the VM Prerequisites everything is on-premises and free (except VM) The only thing you need is: a VM Memory: 16G is recommended Operating system: Ubuntu 22.04 (recommended, other operating systems have no difference except Docker installation) Port:\u00a03000\u00a0port needs to be released for Grafana to use, and\u00a022\u00a0port [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-json\/wp\/v2\/posts\/622","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-json\/wp\/v2\/users\/174024"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-json\/wp\/v2\/comments?post=622"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-json\/wp\/v2\/posts\/622\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-json\/wp\/v2\/media\/12"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-json\/wp\/v2\/media?parent=622"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-json\/wp\/v2\/categories?post=622"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-json\/wp\/v2\/tags?post=622"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}