<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>User guides on Grafana Labs</title><link>https://grafana.com/docs/grafana/v13.3/ai-tools/grafana-cli/gcx/guides/</link><description>Recent content in User guides on Grafana Labs</description><generator>Hugo -- gohugo.io</generator><language>en</language><atom:link href="/docs/grafana/v13.3/ai-tools/grafana-cli/gcx/guides/index.xml" rel="self" type="application/rss+xml"/><item><title>Dashboards as code</title><link>https://grafana.com/docs/grafana/v13.3/ai-tools/grafana-cli/gcx/guides/dashboards-as-code/</link><pubDate>Mon, 12 Oct 2026 15:20:54 +0000</pubDate><guid>https://grafana.com/docs/grafana/v13.3/ai-tools/grafana-cli/gcx/guides/dashboards-as-code/</guid><content><![CDATA[&lt;h1 id=&#34;manage-dashboards-as-code-with-gcx&#34;&gt;Manage dashboards as code with &lt;code&gt;gcx&lt;/code&gt;&lt;/h1&gt;
&lt;p&gt;With this workflow, you can define and manage dashboards as code, saving them to a version control system like Git. This is useful for teams that want to maintain a history of changes, collaborate on dashboard design, and ensure consistency across environments.&lt;/p&gt;
&lt;h2 id=&#34;before-you-begin&#34;&gt;Before you begin&lt;/h2&gt;
&lt;p&gt;In order to use the &lt;code&gt;gcx dev serve&lt;/code&gt; functionality, you need to enable a feature toggle in your configuration file:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;ini&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-ini&#34;&gt;[feature_toggles]
kubernetesDashboards = true&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Refer to &lt;a href=&#34;/docs/grafana/latest/setup-grafana/configure-grafana/#feature_toggles&#34;&gt;Configure Grafana&lt;/a&gt; to learn more about enabling feature toggles.&lt;/p&gt;
&lt;p&gt;Although the local preview proxy supports service account token, Basic, and mTLS contexts, use a service account token instead of OAuth for &lt;code&gt;gcx dev serve&lt;/code&gt;. OAuth is rejected before startup until refresh-token rotation can be persisted safely by the long-running server.&lt;/p&gt;
&lt;h2 id=&#34;workflow&#34;&gt;Workflow&lt;/h2&gt;
&lt;p&gt;To manage dashboards as code with &lt;code&gt;gcx&lt;/code&gt; follow these steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Use a dashboard generation script (for example, with the &lt;a href=&#34;https://github.com/grafana/grafana-foundation-sdk&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Foundation SDK&lt;/a&gt;). You can find an example implementation in the Grafana as code &lt;a href=&#34;https://github.com/grafana/dashboards-as-code-workshop/tree/main/part-one-golang-starter&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;hands-on lab repository&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Serve and preview the output of the dashboard generator locally:

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx config use-context YOUR_CONTEXT  # for example &amp;#34;dev&amp;#34;
gcx dev serve --script &amp;#39;go run scripts/generate-dashboard.go&amp;#39; --watch &amp;#39;./scripts&amp;#39;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;When the output looks correct, generate dashboard manifest files:

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;go run scripts/generate-dashboard.go --generate-resource-manifests --output &amp;#39;./resources&amp;#39;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;Push the generated resources to your Grafana instance:

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx config use-context YOUR_CONTEXT  # for example &amp;#34;dev&amp;#34;
gcx resources push -p ./resources/&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
]]></content><description>&lt;h1 id="manage-dashboards-as-code-with-gcx">Manage dashboards as code with &lt;code>gcx&lt;/code>&lt;/h1>
&lt;p>With this workflow, you can define and manage dashboards as code, saving them to a version control system like Git. This is useful for teams that want to maintain a history of changes, collaborate on dashboard design, and ensure consistency across environments.&lt;/p></description></item><item><title>Explore and modify resources</title><link>https://grafana.com/docs/grafana/v13.3/ai-tools/grafana-cli/gcx/guides/explore-modify-resources/</link><pubDate>Wed, 04 Nov 2026 15:24:35 +0000</pubDate><guid>https://grafana.com/docs/grafana/v13.3/ai-tools/grafana-cli/gcx/guides/explore-modify-resources/</guid><content><![CDATA[&lt;h1 id=&#34;explore-and-modify-resources-with-gcx&#34;&gt;Explore and modify resources with &lt;code&gt;gcx&lt;/code&gt;&lt;/h1&gt;
&lt;p&gt;&lt;code&gt;gcx&lt;/code&gt; allows you to interact with Grafana resources directly from your terminal. You can browse, inspect, update, and delete resources without using the Grafana UI.&lt;/p&gt;
&lt;p&gt;Use this approach if you&amp;rsquo;re an advanced user and want to manage resources more efficiently, or to integrate Grafana operations into automated workflows.&lt;/p&gt;
&lt;h2 id=&#34;search-resources-by-relevance&#34;&gt;Search resources by relevance&lt;/h2&gt;
&lt;p&gt;Use the experimental &lt;code&gt;gcx resources search&lt;/code&gt; command to find ranked matches from a phrase:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx resources search &amp;#34;kubernetes memory problems&amp;#34;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Search returns top matches, without pagination or an exhaustive resource inventory. Scores rank matches in the response.&lt;/p&gt;
&lt;h3 id=&#34;prerequisites&#34;&gt;Prerequisites&lt;/h3&gt;
&lt;p&gt;You need to enable the Grafana global hybrid search endpoint to use &lt;code&gt;gcx resources search&lt;/code&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;On supported Grafana Cloud stacks, &lt;code&gt;gcx resources search&lt;/code&gt; can combine text and semantic matching.&lt;/li&gt;
&lt;li&gt;On self-managed deployments with the endpoint, only use text matching. Semantic matching isn&amp;rsquo;t available on-premises.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Your deployment must have default resource types, or you must select types with &lt;code&gt;--resource&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;search-for-specific-resources&#34;&gt;Search for specific resources&lt;/h3&gt;
&lt;p&gt;Select resource types and exact folder UIDs for a narrower search:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx resources search &amp;#34;memory&amp;#34; \
  --resource dashboards.dashboard.grafana.app \
  --resource folders.folder.grafana.app \
  --folder team-platform \
  --limit 10
gcx resources search &amp;#34;memory&amp;#34; --folder general&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Repeat &lt;code&gt;--resource&lt;/code&gt; to search your selected types instead of the server defaults.&lt;/p&gt;
&lt;p&gt;Repeat &lt;code&gt;--folder&lt;/code&gt; to match any listed folder UID. Folders match exactly, without descendants; &lt;code&gt;general&lt;/code&gt; or &lt;code&gt;--folder &#39;&#39;&lt;/code&gt; selects the root folder. The default limit is 50, and the maximum is 200.&lt;/p&gt;
&lt;p&gt;Use &lt;code&gt;-o wide&lt;/code&gt; to see matching text, or &lt;code&gt;-o json&lt;/code&gt; or &lt;code&gt;-o yaml&lt;/code&gt; for the full response:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx resources search &amp;#34;memory&amp;#34; -o wide
gcx resources search &amp;#34;memory&amp;#34; -o json&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;find-and-delete-dashboards-using-incorrect-data-sources&#34;&gt;Find and delete dashboards using incorrect data sources&lt;/h2&gt;
&lt;p&gt;To identify and remove production dashboards relying on non-production data sources, use the command below to list dashboard UIDs along with the data source UIDs used in their panels:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx resources get dashboards --context prod | jq &amp;#39;.items | map({ uid: .metadata.name, datasources: .spec.panels | map(.datasource.uid)  })&amp;#39;
[
   {
      &amp;#34;uid&amp;#34;: &amp;#34;important-production-dashboard&amp;#34;,
      &amp;#34;datasources&amp;#34;: [
         &amp;#34;mimir-prod&amp;#34;
      ]
   },
   {
      &amp;#34;uid&amp;#34;: &amp;#34;test-dashboard-from-dev&amp;#34;,
      &amp;#34;datasources&amp;#34;: [
         &amp;#34;mimir-dev&amp;#34;
      ]
   },
   {
      &amp;#34;uid&amp;#34;: &amp;#34;test-dashboard-from-stg&amp;#34;,
      &amp;#34;datasources&amp;#34;: [
         &amp;#34;mimir-stg&amp;#34;
      ]
   }
]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Next, identify the dashboards that are using unexpected data sources, and delete them:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx resources delete dashboards/test-dashboard-from-stg,test-dashboard-from-dev
✔ 2 resources deleted, 0 errors&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;edit-remote-resources&#34;&gt;Edit remote resources&lt;/h2&gt;
&lt;p&gt;You can edit resources directly from the default editor, without having to pull them first. To do so, run:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx resources edit dashboard/edit-me-please&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This command opens the default editor set in the &lt;code&gt;EDITOR&lt;/code&gt; environment variable, or falls back to &amp;lsquo;vi&amp;rsquo; for Linux and &amp;rsquo;notepad&amp;rsquo; for Windows.&lt;/p&gt;
&lt;p&gt;After the editor process terminates, the resource is updated in the Grafana instance targeted by the current context. Edition is cancelled if no changes are written to the file, or if the file after edition is empty.&lt;/p&gt;
]]></content><description>&lt;h1 id="explore-and-modify-resources-with-gcx">Explore and modify resources with &lt;code>gcx&lt;/code>&lt;/h1>
&lt;p>&lt;code>gcx&lt;/code> allows you to interact with Grafana resources directly from your terminal. You can browse, inspect, update, and delete resources without using the Grafana UI.&lt;/p></description></item><item><title>Manage resources</title><link>https://grafana.com/docs/grafana/v13.3/ai-tools/grafana-cli/gcx/guides/manage-resources/</link><pubDate>Wed, 04 Nov 2026 15:24:35 +0000</pubDate><guid>https://grafana.com/docs/grafana/v13.3/ai-tools/grafana-cli/gcx/guides/manage-resources/</guid><content><![CDATA[&lt;h1 id=&#34;manage-resources-with-gcx&#34;&gt;Manage resources with &lt;code&gt;gcx&lt;/code&gt;&lt;/h1&gt;
&lt;h2 id=&#34;migrate-resources-between-environments&#34;&gt;Migrate resources between environments&lt;/h2&gt;
&lt;p&gt;Grafana resources can be migrated from one environment to another, for example from a development to production environment.&lt;/p&gt;
&lt;p&gt;You need to &lt;a href=&#34;../../configuration#define-contexts-to-use-different-instances&#34;&gt;configure one context per environment&lt;/a&gt;. In this example scenario, use &lt;code&gt;dev&lt;/code&gt; for the development environment and &lt;code&gt;prod&lt;/code&gt; for production.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Make changes to dashboards and other resources using the Grafana UI in your &lt;strong&gt;development instance&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Pull those resources from the development environment to your local machine:

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx resources pull --context dev # Add `-o yaml` export resources as YAML &lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;Push the resources to production:

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx resources push --context prod&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;Resources are pulled and pushed from the &lt;code&gt;./resources&lt;/code&gt; directory by default.
Configure this path with the &lt;code&gt;--path&lt;/code&gt;/&lt;code&gt;-p&lt;/code&gt; flags.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;h2 id=&#34;name-pulled-files-by-title&#34;&gt;Name pulled files by title&lt;/h2&gt;
&lt;p&gt;By default, &lt;code&gt;gcx resources pull&lt;/code&gt; names each file using the resource&amp;rsquo;s
&lt;code&gt;metadata.name&lt;/code&gt; (usually its UID). Use &lt;code&gt;--filename-by=title&lt;/code&gt; for readable filenames:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx resources pull dashboards --filename-by=title --path ./dashboard-backup&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For example, a dashboard titled &lt;code&gt;Ventas Overview&lt;/code&gt; becomes &lt;code&gt;ventas-overview.json&lt;/code&gt;
inside its usual resource-type directory. Resources without a usable title fall
back to &lt;code&gt;metadata.name&lt;/code&gt;. The resource contents retain their original identity,
so push, validate, and serve use these files normally.&lt;/p&gt;
&lt;p&gt;Title mode resolves filename conflicts, preserving files that belong to other resources. See the
&lt;a href=&#34;https://github.com/grafana/gcx/blob/main/docs/design/naming.md#92-file-naming&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;file naming rules&lt;/a&gt;
for the full algorithm.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;PULL&lt;/code&gt; doesn&amp;rsquo;t remove old files. Title-mode pull warns on stderr when it finds
another file for the same resource at a different path, such as after a rename or
switching naming modes. Reading resources also warns when skipping duplicate
identities. Pull into a clean directory or remove stale files (for example, with
&lt;code&gt;git rm&lt;/code&gt;) before pushing.&lt;/p&gt;
&lt;h2 id=&#34;back-up-and-restore-resources&#34;&gt;Back up and restore resources&lt;/h2&gt;
&lt;p&gt;Follow this workflow to back up all Grafana resources from one instance and later restore them. This can be useful to replicate a configuration or perform disaster recovery.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Ensure the current context points to the Grafana instance to backup/restore:

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx config use-context YOUR_CONTEXT  # for example &amp;#34;prod&amp;#34;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;Pull all resources from your target environment:

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx resources pull --path ./backup-prod # Add `-o yaml` to export resources as YAML&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;Save the exported resources to version control or cloud storage.&lt;/li&gt;
&lt;li&gt;Push the resources to restore them:

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx resources push --path ./backup-prod&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;incident-descriptions&#34;&gt;Incident descriptions&lt;/h2&gt;
&lt;p&gt;Incident descriptions remain visible in &lt;code&gt;GET&lt;/code&gt; and &lt;code&gt;LIST&lt;/code&gt; results.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;PULL&lt;/code&gt; omits descriptions from saved manifests. You cannot restore descriptions if you backed up an incident with &lt;code&gt;gcx resources pull&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Old backup files can contain &lt;code&gt;spec.description&lt;/code&gt;. Remove that field before you push the file to create an
incident or to change an incident with a different description. You can still update other fields.&lt;/p&gt;
]]></content><description>&lt;h1 id="manage-resources-with-gcx">Manage resources with &lt;code>gcx&lt;/code>&lt;/h1>
&lt;h2 id="migrate-resources-between-environments">Migrate resources between environments&lt;/h2>
&lt;p>Grafana resources can be migrated from one environment to another, for example from a development to production environment.&lt;/p></description></item><item><title>Lint resources</title><link>https://grafana.com/docs/grafana/v13.3/ai-tools/grafana-cli/gcx/guides/lint-resources/</link><pubDate>Mon, 12 Oct 2026 15:20:54 +0000</pubDate><guid>https://grafana.com/docs/grafana/v13.3/ai-tools/grafana-cli/gcx/guides/lint-resources/</guid><content><![CDATA[&lt;h1 id=&#34;lint-resources-with-gcx&#34;&gt;Lint resources with &lt;code&gt;gcx&lt;/code&gt;&lt;/h1&gt;
&lt;p&gt;Use the Grafana CLI linter to verify that resources, such as dashboards and alert rules, comply with good practices and environment-specific policies.&lt;/p&gt;
&lt;h2 id=&#34;use-the-linter&#34;&gt;Use the linter&lt;/h2&gt;
&lt;p&gt;To lint resources run:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx dev lint run ./resources&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The following applies:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Directories are recursively explored.&lt;/li&gt;
&lt;li&gt;All &lt;a href=&#34;https://github.com/grafana/gcx/blob/main/docs/reference/linter-rules/index.md&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;built-in rules&lt;/a&gt; are enabled by default.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;configure-linter-rules&#34;&gt;Configure linter rules&lt;/h3&gt;
&lt;p&gt;For a finer control, you can configure the linter rules:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;# Disable all rules for a resource type:
gcx dev lint run --disable-resource dashboard ./resources

# Disable all rules in a category:
gcx dev lint run --disable-category idiomatic ./resources

# Disable specific rules:
gcx dev lint run --disable uneditable-dashboard --disable panel-title-description ./resources

# Enable rules for specific resource types:
gcx dev lint run --disable-all --enable-resource dashboard ./resources

# Enable only some categories:
gcx dev lint run --disable-all --enable-category idiomatic ./resources

# Enable only specific rules:
gcx dev lint run --disable-all --enable uneditable-dashboard ./resources&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You can modify the severity level of a rule by updating the &lt;code&gt;custom.severity&lt;/code&gt; annotation. Valid values are &lt;code&gt;warning&lt;/code&gt; and &lt;code&gt;error&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;define-custom-linting-rules&#34;&gt;Define custom linting rules&lt;/h2&gt;
&lt;p&gt;Custom and built-in rules are defined in &lt;a href=&#34;https://www.openpolicyagent.org/docs/policy-language&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Rego&lt;/a&gt;, the policy language used by &lt;a href=&#34;https://www.openpolicyagent.org/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Open Policy Agent (OPA)&lt;/a&gt;. This ensures that resources comply with policies specific to your environment.&lt;/p&gt;
&lt;p&gt;You can scaffold new custom rules with &lt;code&gt;gcx&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;# Creates a new &amp;#34;dashboard&amp;#34; linter rule in the current directory:
gcx dev lint new dashboard custom-rule&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This generates a file with the bootstrapped rule:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;rego&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-rego&#34;&gt;# METADATA
# description: Briefly describe the rule here.
# custom:
#  severity: warning
package custom.gcx.rules.dashboard.idiomatic[&amp;#34;custom-rule&amp;#34;]

import data.gcx.result
import data.gcx.utils

# Dashboard v1
report contains violation if {
	utils.resource_is_dashboard_v1(input)

	input.spec.timezone != &amp;#34;utc&amp;#34;

	violation := result.fail(rego.metadata.chain(), sprintf(&amp;#34;timezone is &amp;#39;%s&amp;#39;, expected &amp;#39;utc&amp;#39;&amp;#34;, input.spec.timezone))
}

# Dashboard v2
report contains violation if {
	utils.resource_is_dashboard_v2(input)

	input.spec.timeSettings.timezone != &amp;#34;utc&amp;#34;

	violation := result.fail(rego.metadata.chain(), sprintf(&amp;#34;timezone is &amp;#39;%s&amp;#39;, expected &amp;#39;utc&amp;#39;&amp;#34;, input.spec.timeSettings.timezone))
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Refer to the existing &lt;a href=&#34;https://github.com/grafana/gcx/tree/main/internal/linter/bundle/gcx/rules&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Built-in rules&lt;/a&gt; for inspiration to write custom ones.&lt;/p&gt;
&lt;h3 id=&#34;rules-for-other-resources&#34;&gt;Rules for other resources&lt;/h3&gt;
&lt;p&gt;You can create rules for other resource types than dashboards, or in categories other than &lt;code&gt;idiomatic&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;# Creates a new &amp;#34;alertrule&amp;#34; linter rule, categorized under &amp;#34;bug&amp;#34;:
gcx dev lint new alertrule custom-rule -c bug&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="lint-resources-with-gcx">Lint resources with &lt;code>gcx&lt;/code>&lt;/h1>
&lt;p>Use the Grafana CLI linter to verify that resources, such as dashboards and alert rules, comply with good practices and environment-specific policies.&lt;/p></description></item><item><title>Diagnose missing telemetry</title><link>https://grafana.com/docs/grafana/v13.3/ai-tools/grafana-cli/gcx/guides/diagnose-missing-telemetry/</link><pubDate>Mon, 12 Oct 2026 15:20:54 +0000</pubDate><guid>https://grafana.com/docs/grafana/v13.3/ai-tools/grafana-cli/gcx/guides/diagnose-missing-telemetry/</guid><content><![CDATA[&lt;h1 id=&#34;diagnose-missing-telemetry-with-gcx&#34;&gt;Diagnose missing telemetry with &lt;code&gt;gcx&lt;/code&gt;&lt;/h1&gt;
&lt;p&gt;If you&amp;rsquo;re investigating an empty dashboard or missing application telemetry, use this guide to learn how to use &lt;code&gt;gcx&lt;/code&gt; to gather evidence before proposing a repair. You don&amp;rsquo;t need a new diagnostic skill or Grafana Cloud.&lt;/p&gt;
&lt;p&gt;You can investigate directly or use an agent with &lt;code&gt;gcx&lt;/code&gt; existing skills. Start with evidence, ask before repairs, and verify the original symptom afterward. If you use an agent, its harness and model access are separate from &lt;code&gt;gcx&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;before-you-begin&#34;&gt;Before you begin&lt;/h2&gt;
&lt;p&gt;Before you begin, make sure to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Follow &lt;a href=&#34;../../installation&#34;&gt;Install gcx&lt;/a&gt; if &lt;code&gt;gcx version&lt;/code&gt; is unavailable.&lt;/li&gt;
&lt;li&gt;Follow &lt;a href=&#34;https://github.com/grafana/gcx#install-agent-skills&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Install Agent Skills&lt;/a&gt; for your harness. Start a session that can discover the installed skills. The existing &lt;code&gt;debug-with-grafana&lt;/code&gt; skill handles investigation; &lt;code&gt;setup-gcx&lt;/code&gt; helps with setup.&lt;/li&gt;
&lt;li&gt;Use a reachable Grafana instance supported by your &lt;code&gt;gcx&lt;/code&gt; version, with access to the relevant datasources. A static instrumentation check alone does not provide a telemetry destination.&lt;/li&gt;
&lt;li&gt;If you have no backend, &lt;a href=&#34;https://github.com/grafana/docker-otel-lgtm#run-the-docker-image&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;start docker-otel-lgtm&lt;/a&gt;   for a local development sink. Setting up a sink does not authorize changing an existing application&amp;rsquo;s exporter. A local proof does not establish that your production destination works.&lt;/li&gt;
&lt;li&gt;Know which application or fixture you may inspect. Do not enumerate unrelated containers, environments, or services to compensate for missing context.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The command examples use the current &lt;code&gt;gcx&lt;/code&gt; command surface. Check &lt;code&gt;gcx version&lt;/code&gt; and the relevant command&amp;rsquo;s &lt;code&gt;--help&lt;/code&gt; when following them with another release.&lt;/p&gt;
&lt;h2 id=&#34;connect-without-changing-your-usual-context&#34;&gt;Connect without changing your usual context&lt;/h2&gt;
&lt;p&gt;If you have already configured the destination, use explicit &lt;code&gt;--config&lt;/code&gt; and &lt;code&gt;--context&lt;/code&gt; arguments. Don&amp;rsquo;t switch the current context just for this investigation. Otherwise, create a separate private configuration outside your checkout.&lt;/p&gt;
&lt;p&gt;The examples use &lt;code&gt;GCX_CONFIG&lt;/code&gt;, the actual &lt;code&gt;gcx&lt;/code&gt; environment override. If it&amp;rsquo;s pointing at another configuration, unset it first:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;GCX_DIAGNOSTICS_DIR=$(mktemp -d)
export GCX_CONFIG=&amp;#34;$GCX_DIAGNOSTICS_DIR/config.yaml&amp;#34;
(umask 077; printf &amp;#39;{}\n&amp;#39; &amp;gt; &amp;#34;$GCX_CONFIG&amp;#34;)&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Keep the path until cleanup. In another terminal, set the variable to the same path; don&amp;rsquo;t create a second empty configuration by repeating the block.&lt;/p&gt;
&lt;h3 id=&#34;log-in&#34;&gt;Log in&lt;/h3&gt;
&lt;p&gt;For an existing Grafana destination, use interactive login with a new context in that file, replacing the example URL:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;gcx login diagnostics --config &amp;#34;$GCX_CONFIG&amp;#34; \
  --server https://your-grafana.example&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For local LGTM, use that repository&amp;rsquo;s local connection instructions instead of this login step. Refer to &lt;a href=&#34;../../configuration&#34;&gt;Configure gcx&lt;/a&gt; for supported authentication methods. &lt;strong&gt;Supply credentials locally through the supported authentication flow&lt;/strong&gt;, not in chat, copied transcripts, or committed files. Prefer read-only access when available as approval instructions don&amp;rsquo;t restrict API permissions.&lt;/p&gt;
&lt;h3 id=&#34;check-the-overrides&#34;&gt;Check the overrides&lt;/h3&gt;
&lt;p&gt;Environment overrides can still affect the selected configuration. Review which overrides you intentionally set before running queries and don&amp;rsquo;t dump your whole environment or configuration into a transcript. Don&amp;rsquo;t disable TLS verification to make a connection error disappear.&lt;/p&gt;
&lt;p&gt;Use your selected context name below, where &lt;code&gt;diagnostics&lt;/code&gt; is the login example:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;gcx config check --config &amp;#34;$GCX_CONFIG&amp;#34; --context diagnostics
gcx datasources list --config &amp;#34;$GCX_CONFIG&amp;#34; --context diagnostics&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;verify-the-connection-and-authentication&#34;&gt;Verify the connection and authentication&lt;/h3&gt;
&lt;p&gt;Stop and resolve any connection or authentication errors before interpreting query results.&lt;/p&gt;
&lt;p&gt;For example, against a Prometheus datasource:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;gcx metrics query &amp;#39;vector(1)&amp;#39; --datasource &amp;#39;PROMETHEUS_DATASOURCE_UID&amp;#39; \
  --error-on-empty \
  --config &amp;#34;$GCX_CONFIG&amp;#34; --context diagnostics&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Keep in mind the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Choose the datasource UID returned by discovery, rather than assuming a default.&lt;/li&gt;
&lt;li&gt;A successful configuration check doesn&amp;rsquo;t prove application ingestion.&lt;/li&gt;
&lt;li&gt;A returned value proves that query path works, not that the application emitted metrics.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With &lt;code&gt;--error-on-empty&lt;/code&gt;, an empty response exits unsuccessfully; without it, a successful empty query, an invalid query, and a failed connection are different observations. The flag is supported on the Prometheus query, Loki logs/metrics, Tempo search/metrics, and Pyroscope query commands, but it&amp;rsquo;s not a generic flag for unrelated datasource query commands.&lt;/p&gt;
&lt;h2 id=&#34;use-an-agent-for-diagnostics&#34;&gt;Use an agent for diagnostics&lt;/h2&gt;
&lt;p&gt;Start the agent in the relevant application or test checkout, and provide it with the symptoms and boundaries for diagnostics:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The original dashboard URL, failed test assertion, or checker finding.&lt;/li&gt;
&lt;li&gt;The explicit gcx config path, context, and intended destination (no secrets).&lt;/li&gt;
&lt;li&gt;The application/service identity and one representative operation, if known.&lt;/li&gt;
&lt;li&gt;The UTC time window, observed query, and request/trace identifiers, if available.&lt;/li&gt;
&lt;li&gt;The relevant Compose project, deployment, or Collector configuration you own.&lt;/li&gt;
&lt;li&gt;Which resources may be inspected and which actions require approval.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Make sure the agent doesn&amp;rsquo;t invent answers and to identify what information or access is missing. For example, use this prompt, filling in what you know:&lt;/p&gt;

&lt;div class=&#34;code-snippet code-snippet__mini&#34;&gt;&lt;div class=&#34;lang-toolbar__mini&#34;&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet code-snippet__border&#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-none&#34;&gt;Use the existing gcx skills to investigate `&amp;lt;symptom&amp;gt;`. Query only `&amp;lt;config path and context&amp;gt;` and inspect only `&amp;lt;application/fixture scope&amp;gt;`. The expected operation is `&amp;lt;operation&amp;gt;` in `&amp;lt;time window&amp;gt;`. Diagnose first and distinguish observed evidence from hypotheses. State what you could not observe; do not infer data loss from missing access. Ask before changing application, Collector, dashboard, or test configuration, restarting resources, or enabling payload logging. Do not weaken an assertion to make a test pass. Propose the smallest justified repair, and stop for approval.&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;An empty dashboard can result from no data being created, export failure, filtering, an incorrect query, or a time/identity mismatch. Static configuration and absence of results are leads, not proof of a particular failure boundary.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Always ask for the evidence supporting each conclusion and the next discriminating check&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&#34;verify-a-repair-and-restore-the-environment&#34;&gt;Verify a repair and restore the environment&lt;/h2&gt;
&lt;p&gt;After approving a specific change:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Exercise a fresh representative operation and record its time and available identifiers. Old telemetry must not satisfy the recovery check.&lt;/li&gt;
&lt;li&gt;Query the relevant datasource, then recheck the original dashboard or rerun the original test uncached. A successful backend query alone does not prove the panel or assertion is correct.&lt;/li&gt;
&lt;li&gt;Review the actual diff and runtime changes. Functional recovery doesn&amp;rsquo;t prove that unrelated dashboard or configuration fields were preserved.&lt;/li&gt;
&lt;li&gt;Restore temporary diagnostic configuration and logging. Remove temporary backups and stop only resources created for this investigation, after confirming they are no longer needed. Never clean up pre-existing resources by assumption.&lt;/li&gt;
&lt;li&gt;Record the confirmed cause, remaining unknowns, approved changes, and result.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Debug-exporter payloads and logs may contain sensitive data. Enable them only with permission, for a bounded investigation, and never publish raw output. Avoid full environment dumps or HTTP payload logging that can expose credentials.&lt;/p&gt;
&lt;p&gt;If you created the private directory above, inspect it locally and remove only that directory when finished. Remove any diagnostic credentials stored by login using your normal credential-management process; deleting a config file doesn&amp;rsquo;t revoke a server-side token. Explicit configuration or context arguments leave your usual current context unchanged. Don&amp;rsquo;t delete an existing configuration used for the investigation, or revoke a credential shared with another workflow.&lt;/p&gt;
]]></content><description>&lt;h1 id="diagnose-missing-telemetry-with-gcx">Diagnose missing telemetry with &lt;code>gcx&lt;/code>&lt;/h1>
&lt;p>If you&amp;rsquo;re investigating an empty dashboard or missing application telemetry, use this guide to learn how to use &lt;code>gcx&lt;/code> to gather evidence before proposing a repair. You don&amp;rsquo;t need a new diagnostic skill or Grafana Cloud.&lt;/p></description></item><item><title>Manage Machine Learning resources</title><link>https://grafana.com/docs/grafana/v13.3/ai-tools/grafana-cli/gcx/guides/manage-machine-learning/</link><pubDate>Mon, 02 Nov 2026 08:26:02 +0000</pubDate><guid>https://grafana.com/docs/grafana/v13.3/ai-tools/grafana-cli/gcx/guides/manage-machine-learning/</guid><content><![CDATA[&lt;h1 id=&#34;manage-machine-learning-resources&#34;&gt;Manage Machine Learning resources&lt;/h1&gt;
&lt;p&gt;Use &lt;code&gt;gcx ml&lt;/code&gt; to manage Grafana Cloud Machine Learning resources.&lt;/p&gt;
&lt;h2 id=&#34;prerequisites&#34;&gt;Prerequisites&lt;/h2&gt;
&lt;p&gt;The following applies:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Your Grafana stack must have &lt;a href=&#34;/docs/grafana-cloud/ai-tools/machine-learning/&#34;&gt;Machine Learning&lt;/a&gt; enabled.&lt;/li&gt;
&lt;li&gt;You don&amp;rsquo;t need a separate provider token. The commands use the active Grafana credential through the Machine Learning plugin proxy.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;inspect-resources&#34;&gt;Inspect resources&lt;/h2&gt;
&lt;p&gt;Forecasts are jobs in the Machine Learning API.&lt;/p&gt;
&lt;p&gt;Use the server IDs from the list output with &lt;code&gt;get&lt;/code&gt;, &lt;code&gt;update&lt;/code&gt;, and &lt;code&gt;delete&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx ml jobs list
gcx ml holidays list
gcx ml outlier-detectors list
gcx ml jobs get &amp;lt;job-id&amp;gt; -o yaml&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Use &lt;code&gt;--json&lt;/code&gt; or &lt;code&gt;--jq&lt;/code&gt; to select output fields.&lt;/p&gt;
&lt;h3 id=&#34;configure-the-number-of-records-in-the-output&#34;&gt;Configure the number of records in the output&lt;/h3&gt;
&lt;p&gt;Lists fetch all records from the collection endpoint and show up to 50 records by default:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;--limit 0&lt;/code&gt; to show all records.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;--limit 10&lt;/code&gt; to show fewer records. A truncation notice appears on &lt;code&gt;stderr&lt;/code&gt; when records are omitted.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;apply-a-resource&#34;&gt;Apply a resource&lt;/h2&gt;
&lt;p&gt;Use a resource example to create a manifest. Set the datasource UID and the query for your target stack:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx resources list-examples jobs.ml.ext.grafana.app --jq &amp;#39;.[&amp;#34;ml.ext.grafana.app&amp;#34;].v1alpha1[0].example&amp;#39; -o json &amp;gt; job.json
gcx ml jobs create -f job.json --dry-run
gcx ml jobs create -f job.json
gcx ml jobs update &amp;lt;job-id&amp;gt; -f job.json&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;Creating or updating a forecast job can start model training.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;--dry-run&lt;/code&gt; checks the input without a server mutation. The result reports that server validation is not available.&lt;/p&gt;
&lt;h3 id=&#34;delete-a-resource&#34;&gt;Delete a resource&lt;/h3&gt;
&lt;p&gt;Delete commands require confirmation or &lt;code&gt;--force&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;export-and-push-manifests&#34;&gt;Export and push manifests&lt;/h2&gt;
&lt;p&gt;Jobs, holidays, and outlier detectors use the standard resource pipeline. The provider removes server IDs and connection fields from each spec.&lt;/p&gt;
&lt;h3 id=&#34;target-stack&#34;&gt;Target stack&lt;/h3&gt;
&lt;p&gt;Each write uses the target stack URL. The server ID from the source stack is stored in &lt;code&gt;metadata.name&lt;/code&gt;. If that ID doesn&amp;rsquo;t exist on the target, the pipeline matches the normalized value of &lt;code&gt;spec.name&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Each write resolves the numeric datasource ID from the UID on the target stack.
Writes need read access to the selected datasource.&lt;/p&gt;
&lt;p&gt;Matching:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Converts names to lowercase slugs.&lt;/li&gt;
&lt;li&gt;Updates one matching resource or creates a resource when there is no match.&lt;/li&gt;
&lt;li&gt;Multiple matches are rejected.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;push-cross-stack&#34;&gt;Push cross-stack&lt;/h3&gt;
&lt;p&gt;Data source UIDs and job-to-holiday references remain in the spec. Set these references for the target stack before a cross-stack push.&lt;/p&gt;
&lt;p&gt;After a cross-stack push, pull from the target to save its assigned IDs:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx resources push -p ./ml --dry-run
gcx resources push -p ./ml
gcx resources pull jobs.ml.ext.grafana.app holidays.ml.ext.grafana.app outlierdetectors.ml.ext.grafana.app -p ./ml&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;manage-parent-alerts&#34;&gt;Manage parent alerts&lt;/h2&gt;
&lt;p&gt;Machine Learning alerts belong to a job or an outlier detector, and have no independent collection endpoint or resource adapter.
Use the parent ID with the alert commands.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx ml jobs list-alerts &amp;lt;job-id&amp;gt;
gcx ml jobs get-alert &amp;lt;job-id&amp;gt; &amp;lt;alert-id&amp;gt; -o yaml
gcx ml jobs create-alert &amp;lt;job-id&amp;gt; -f alert.yaml
gcx ml jobs update-alert &amp;lt;job-id&amp;gt; &amp;lt;alert-id&amp;gt; -f alert.yaml
gcx ml jobs delete-alert &amp;lt;job-id&amp;gt; &amp;lt;alert-id&amp;gt; --force
gcx ml outlier-detectors list-alerts &amp;lt;detector-id&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The same alert operations are available under &lt;code&gt;outlier-detectors&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;alert-objects&#34;&gt;Alert objects&lt;/h3&gt;
&lt;p&gt;Alert files contain the Machine Learning alert object, including its &lt;code&gt;title&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Use &lt;code&gt;get-alert&lt;/code&gt; to export an alert object before you edit it.&lt;/p&gt;
&lt;h3 id=&#34;outlier-alerts&#34;&gt;Outlier alerts&lt;/h3&gt;
&lt;p&gt;Outlier alerts require a nonzero &lt;code&gt;window&lt;/code&gt;, such as &lt;code&gt;5m&lt;/code&gt;. Don&amp;rsquo;t set &lt;code&gt;threshold&lt;/code&gt; or &lt;code&gt;anomalyCondition&lt;/code&gt; for an outlier alert.&lt;/p&gt;
]]></content><description>&lt;h1 id="manage-machine-learning-resources">Manage Machine Learning resources&lt;/h1>
&lt;p>Use &lt;code>gcx ml&lt;/code> to manage Grafana Cloud Machine Learning resources.&lt;/p>
&lt;h2 id="prerequisites">Prerequisites&lt;/h2>
&lt;p>The following applies:&lt;/p>
&lt;ul>
&lt;li>Your Grafana stack must have &lt;a href="/docs/grafana-cloud/ai-tools/machine-learning/">Machine Learning&lt;/a> enabled.&lt;/li>
&lt;li>You don&amp;rsquo;t need a separate provider token. The commands use the active Grafana credential through the Machine Learning plugin proxy.&lt;/li>
&lt;/ul>
&lt;h2 id="inspect-resources">Inspect resources&lt;/h2>
&lt;p>Forecasts are jobs in the Machine Learning API.&lt;/p></description></item><item><title>Manage OnCall notification rules</title><link>https://grafana.com/docs/grafana/v13.3/ai-tools/grafana-cli/gcx/guides/manage-oncall-notification-rules/</link><pubDate>Mon, 02 Nov 2026 08:26:02 +0000</pubDate><guid>https://grafana.com/docs/grafana/v13.3/ai-tools/grafana-cli/gcx/guides/manage-oncall-notification-rules/</guid><content><![CDATA[&lt;h1 id=&#34;manage-oncall-personal-notification-rules&#34;&gt;Manage OnCall personal notification rules&lt;/h1&gt;
&lt;p&gt;You can use &lt;code&gt;gcx&lt;/code&gt; to manage OnCall personal notification rules&lt;/p&gt;
&lt;h2 id=&#34;authentication-and-permissions&#34;&gt;Authentication and permissions&lt;/h2&gt;
&lt;p&gt;Use &lt;code&gt;gcx login&lt;/code&gt; to sign in as a Grafana user.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The command uses the shared Grafana authentication transport and the IRM plugin proxy, and it doesn&amp;rsquo;t need a separate OnCall API key.&lt;/li&gt;
&lt;li&gt;Service account requests are rejected by the server.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The server requires &lt;code&gt;grafana-oncall-app.user-settings:read&lt;/code&gt; for reads and &lt;code&gt;grafana-oncall-app.user-settings:write&lt;/code&gt; for changes. Changes to another user&amp;rsquo;s rules also require &lt;code&gt;grafana-oncall-app.user-settings:admin&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;manage-oncall-notification-rules&#34;&gt;Manage OnCall notification rules&lt;/h2&gt;
&lt;p&gt;To get a list of rules for all users and priority levels, run:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;gcx irm oncall personal-notification-rules list
gcx irm oncall personal-notification-rules get &amp;lt;rule-id&amp;gt;
gcx resources list-examples personalnotificationrules&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Manage rules with these commands:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Create rules with &lt;code&gt;create -f rule.yaml&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Update rules with &lt;code&gt;update &amp;lt;rule-id&amp;gt; -f rule.yaml&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Delete rules with &lt;code&gt;delete &amp;lt;rule-id&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;rule-fields&#34;&gt;Rule fields&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Do not use the public API&amp;rsquo;s &lt;code&gt;type&lt;/code&gt; or &lt;code&gt;duration&lt;/code&gt; field names.&lt;/strong&gt; &lt;code&gt;step&lt;/code&gt;, &lt;code&gt;notify_by&lt;/code&gt;, and &lt;code&gt;wait_delay&lt;/code&gt; use the internal IRM API values.&lt;/p&gt;
&lt;p&gt;Rule fields such as &lt;code&gt;user&lt;/code&gt; and &lt;code&gt;important&lt;/code&gt; are set when the rule is created, and are ignored in updates.&lt;/p&gt;
&lt;p&gt;Use a string of seconds for &lt;code&gt;wait_delay&lt;/code&gt;, such as &lt;code&gt;&amp;quot;300.0&amp;quot;&lt;/code&gt;, or &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The server assigns its own rule ID at creation. Use the returned ID for later updates. For resource pushes, pull the created rule and keep that manifest before the next push. Its &lt;code&gt;metadata.name&lt;/code&gt; contains the server ID. The server also controls &lt;code&gt;order&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The API can also return &lt;code&gt;notify_device&lt;/code&gt;. &lt;code&gt;gcx&lt;/code&gt; preserves this server field in exports and updates. It&amp;rsquo;s &lt;code&gt;null&lt;/code&gt; when the rule has no selected device.&lt;/p&gt;
&lt;h3 id=&#34;routes&#34;&gt;Routes&lt;/h3&gt;
&lt;p&gt;The &lt;strong&gt;proxy route&lt;/strong&gt; is &lt;code&gt;notification_policies/&lt;/code&gt;, and uses the same &lt;code&gt;UserNotificationPolicy&lt;/code&gt; model as the public OnCall &lt;code&gt;/api/v1/personal_notification_rules/&lt;/code&gt; route.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;public route&lt;/strong&gt; requires an OnCall API token in the raw &lt;code&gt;Authorization&lt;/code&gt; header. A Grafana OAuth token is used through the plugin proxy instead.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;internal route&lt;/strong&gt; defaults to the current user and &lt;code&gt;important=false&lt;/code&gt; when query parameters are absent.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;gcx&lt;/code&gt; sends &lt;code&gt;?user=&amp;amp;important=&lt;/code&gt; to disable these defaults. The backend then returns the full collection. The resource adapter uses the same client methods as the provider commands.&lt;/p&gt;
&lt;h2 id=&#34;select-a-step-and-notification-channel&#34;&gt;Select a step and notification channel&lt;/h2&gt;
&lt;p&gt;Use these internal API values for &lt;code&gt;step&lt;/code&gt;:&lt;/p&gt;
&lt;section class=&#34;expand-table-wrapper&#34;&gt;&lt;div class=&#34;button-div&#34;&gt;
      &lt;button class=&#34;expand-table-btn&#34;&gt;Expand table&lt;/button&gt;
    &lt;/div&gt;&lt;div class=&#34;responsive-table-wrapper&#34;&gt;
    &lt;table&gt;
      &lt;thead&gt;
          &lt;tr&gt;
              &lt;th&gt;Value&lt;/th&gt;
              &lt;th&gt;Step&lt;/th&gt;
          &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;code&gt;0&lt;/code&gt;&lt;/td&gt;
              &lt;td&gt;Wait for &lt;code&gt;wait_delay&lt;/code&gt; seconds&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
              &lt;td&gt;Notify through &lt;code&gt;notify_by&lt;/code&gt;&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/section&gt;&lt;p&gt;A wait step returns &lt;code&gt;notify_by: null&lt;/code&gt;. The default table shows a dash for that value and shows the wait duration in &lt;code&gt;WAIT-DELAY&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;notification-channels&#34;&gt;Notification channels&lt;/h3&gt;
&lt;p&gt;Notification channels depend on the stack and its integrations. Read the live catalog to get the available values and display names:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;gcx api /api/plugins/grafana-irm-app/resources/notification_policies/notify_by_options/&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Common &lt;code&gt;notify_by&lt;/code&gt; values are:&lt;/p&gt;
&lt;section class=&#34;expand-table-wrapper&#34;&gt;&lt;div class=&#34;button-div&#34;&gt;
      &lt;button class=&#34;expand-table-btn&#34;&gt;Expand table&lt;/button&gt;
    &lt;/div&gt;&lt;div class=&#34;responsive-table-wrapper&#34;&gt;
    &lt;table&gt;
      &lt;thead&gt;
          &lt;tr&gt;
              &lt;th&gt;Value&lt;/th&gt;
              &lt;th&gt;Channel&lt;/th&gt;
          &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;code&gt;0&lt;/code&gt;&lt;/td&gt;
              &lt;td&gt;Slack mentions&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
              &lt;td&gt;SMS&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;code&gt;2&lt;/code&gt;&lt;/td&gt;
              &lt;td&gt;Phone call&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;code&gt;3&lt;/code&gt;&lt;/td&gt;
              &lt;td&gt;Telegram&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;code&gt;5&lt;/code&gt;&lt;/td&gt;
              &lt;td&gt;Mobile push&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;code&gt;6&lt;/code&gt;&lt;/td&gt;
              &lt;td&gt;Mobile push important&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;code&gt;7&lt;/code&gt;&lt;/td&gt;
              &lt;td&gt;Microsoft Teams&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;code&gt;8&lt;/code&gt;&lt;/td&gt;
              &lt;td&gt;Email&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;code&gt;11&lt;/code&gt;&lt;/td&gt;
              &lt;td&gt;Webhook&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/section&gt;]]></content><description>&lt;h1 id="manage-oncall-personal-notification-rules">Manage OnCall personal notification rules&lt;/h1>
&lt;p>You can use &lt;code>gcx&lt;/code> to manage OnCall personal notification rules&lt;/p>
&lt;h2 id="authentication-and-permissions">Authentication and permissions&lt;/h2>
&lt;p>Use &lt;code>gcx login&lt;/code> to sign in as a Grafana user.&lt;/p></description></item><item><title>Compare profiles</title><link>https://grafana.com/docs/grafana/v13.3/ai-tools/grafana-cli/gcx/guides/compare-profiles/</link><pubDate>Wed, 28 Oct 2026 16:28:10 +0000</pubDate><guid>https://grafana.com/docs/grafana/v13.3/ai-tools/grafana-cli/gcx/guides/compare-profiles/</guid><content><![CDATA[&lt;h1 id=&#34;compare-profiles-with-gcx&#34;&gt;Compare profiles with &lt;code&gt;gcx&lt;/code&gt;&lt;/h1&gt;
&lt;p&gt;You can compare profiles with &lt;code&gt;gcx&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;gcx profiles query&lt;/code&gt; for one profile.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;gcx profiles diff&lt;/code&gt; for symbol costs across selectors, time windows, or both. &lt;code&gt;diff&lt;/code&gt; uses &lt;a href=&#34;/docs/pyroscope/latest/&#34;&gt;Pyroscope&lt;/a&gt;&amp;rsquo;s server-side comparison, not independently truncated top-function lists.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Follow these steps to compare profiles:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Configure a Grafana context with read access to Pyroscope.&lt;/li&gt;
&lt;li&gt;Find the datasource UID with &lt;code&gt;gcx datasources list --type pyroscope&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Find the profile type with &lt;code&gt;gcx profiles list-profile-types -d &amp;lt;datasource-uid&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Run then following commands to compare:&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx profiles diff &amp;#39;{service_name=&amp;#34;frontend&amp;#34;,version=&amp;#34;v1&amp;#34;}&amp;#39; &amp;#39;{service_name=&amp;#34;frontend&amp;#34;,version=&amp;#34;v2&amp;#34;}&amp;#39; \
  -d &amp;lt;datasource-uid&amp;gt; --profile-type process_cpu:cpu:nanoseconds:cpu:nanoseconds \
  --before-from now-1h --before-to now \
  --after-from now-1h --after-to now --drilldown-link&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In this example, both sides share a datasource and profile type. Repeat the same selector to compare different windows. Unsupported selectors warn and fall back without dropping scope.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Use fixed timestamps for reproducible evidence&lt;/strong&gt;. All four bounds are required: RFC3339, Unix seconds, or relative times. They use one clock snapshot and resolve to whole seconds to match Drilldown.&lt;/p&gt;
&lt;p&gt;Dedicated comparisons require the same exact &lt;code&gt;service_name&lt;/code&gt;. Names requiring string escaping fall back to Explore, while other matchers are preserved separately.&lt;/p&gt;
&lt;p&gt;For a profile UUID from exemplars, add &lt;code&gt;--profile-id &amp;lt;uuid&amp;gt; --drilldown-link&lt;/code&gt; to &lt;code&gt;gcx profiles query&lt;/code&gt;. A single ID opens the scoped flame graph and multiple IDs or stacktrace selectors fall back to Explore. Trace-ID-scoped queries suppress links because neither UI can preserve their scope.&lt;/p&gt;
&lt;h2 id=&#34;interpret-costs&#34;&gt;Interpret costs&lt;/h2&gt;
&lt;p&gt;Table-wide output shows the top 20 absolute self-cost changes.&lt;/p&gt;
&lt;p&gt;JSON, YAML, and agents output retain all returned symbols, warnings, selections, units, and links. The backend node budget defaults to 50,000 in every format.&lt;/p&gt;
&lt;p&gt;Take into account the following to interpret costs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Costs use the profile type&amp;rsquo;s raw sample unit.&lt;/li&gt;
&lt;li&gt;Recursive inclusive costs count only the outermost occurrence per stack.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;self&lt;/code&gt; attributes cost directly to a function.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;total&lt;/code&gt; includes callees.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;delta&lt;/code&gt; is after minus before, without duration or traffic normalization.&lt;/li&gt;
&lt;li&gt;Prefer comparable, equal-length windows: traffic, replicas, and sampling can change cost without a regression.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;changePercent&lt;/code&gt; is null for zero baselines or when either profile has no positive samples. Missing samples do not establish zero cost or improvement.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;complete=false&lt;/code&gt; means frames were folded into &lt;code&gt;other&lt;/code&gt;; &lt;code&gt;omitted&lt;/code&gt; reports their costs.&lt;/li&gt;
&lt;li&gt;Raise &lt;code&gt;--max-nodes&lt;/code&gt; or narrow selectors to improve attribution.&lt;/li&gt;
&lt;li&gt;Absence from a pruned graph does not establish an added or removed function.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;share-evidence&#34;&gt;Share evidence&lt;/h2&gt;
&lt;p&gt;To share evidence:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;links.before&lt;/code&gt; and &lt;code&gt;links.after&lt;/code&gt; open individual profiles.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;links.explore&lt;/code&gt; opens before on the left and after on the right, with independent ranges.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;links.comparison&lt;/code&gt; opens the dedicated diff view when representable.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The following options are available:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--share-link&lt;/code&gt; / &lt;code&gt;--open&lt;/code&gt;: print or open split Explore.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--drilldown-link&lt;/code&gt; / &lt;code&gt;--open-drilldown&lt;/code&gt;: print or open Profiles Drilldown. You must enable Drilldown, since URLs target its Scenes contract used in version 3.1.0. Use Explore for older apps that don&amp;rsquo;t support that contract.&lt;/li&gt;
&lt;/ul&gt;
]]></content><description>&lt;h1 id="compare-profiles-with-gcx">Compare profiles with &lt;code>gcx&lt;/code>&lt;/h1>
&lt;p>You can compare profiles with &lt;code>gcx&lt;/code>:&lt;/p>
&lt;ul>
&lt;li>Use &lt;code>gcx profiles query&lt;/code> for one profile.&lt;/li>
&lt;li>Use &lt;code>gcx profiles diff&lt;/code> for symbol costs across selectors, time windows, or both. &lt;code>diff&lt;/code> uses &lt;a href="/docs/pyroscope/latest/">Pyroscope&lt;/a>&amp;rsquo;s server-side comparison, not independently truncated top-function lists.&lt;/li>
&lt;/ul>
&lt;p>Follow these steps to compare profiles:&lt;/p></description></item><item><title>Manage Assistant Watchers</title><link>https://grafana.com/docs/grafana/v13.3/ai-tools/grafana-cli/gcx/guides/manage-assistant-watchers/</link><pubDate>Thu, 22 Oct 2026 08:20:30 +0000</pubDate><guid>https://grafana.com/docs/grafana/v13.3/ai-tools/grafana-cli/gcx/guides/manage-assistant-watchers/</guid><content><![CDATA[&lt;h1 id=&#34;manage-assistant-watchers&#34;&gt;Manage Assistant Watchers&lt;/h1&gt;
&lt;p&gt;Use &lt;code&gt;gcx&lt;/code&gt; to create Watchers and keep their configuration in version control. &lt;strong&gt;Watcher commands are experimental and require Grafana Cloud&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&#34;before-you-begin&#34;&gt;Before you begin&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;../../configuration/&#34;&gt;Configure a gcx context&lt;/a&gt; for a Grafana Cloud stack with Assistant Watchers enabled.&lt;/li&gt;
&lt;li&gt;Make sure your identity can read and manage Watchers and access the data sources you want to monitor.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Commands use your selected context. Add &lt;code&gt;--context CONTEXT&lt;/code&gt; to select another context.&lt;/p&gt;
&lt;h2 id=&#34;create-a-watcher-and-follow-calibration&#34;&gt;Create a Watcher and follow calibration&lt;/h2&gt;
&lt;p&gt;To create a Watcher, follow these steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Save the following manifest as &lt;code&gt;watcher.yaml&lt;/code&gt;. Replace &lt;code&gt;DATASOURCE_UID&lt;/code&gt; with an accessible data source UID.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;apiVersion: assistant.ext.grafana.app/v1alpha1
kind: Watcher
metadata:
  name: checkout-health
spec:
  title: Checkout health
  prompt: Watch request failures and sustained latency increases.
  datasourceUids: [DATASOURCE_UID]
  interval: 15m
  sensitivity: balanced&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create the Watcher:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx assistant watchers create -f watcher.yaml -o json&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The result includes the saved resource and a separate calibration request outcome. Creation requests background calibration without automatically starting monitoring. Notification destinations and investigations are disabled unless you enable them in the manifest. Watcher calibration and runs consume Grafana Assistant tokens; refer to &lt;a href=&#34;/docs/grafana-cloud/platform/pricing-and-usage/assistant/&#34;&gt;Assistant pricing&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Replace &lt;code&gt;WATCHER&lt;/code&gt; with the returned resource name or ID and inspect progress:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx assistant watchers status WATCHER -o json&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;An &lt;code&gt;accepted&lt;/code&gt; request means calibration was requested, not that checks are ready. Wait while it is queued or running. If calibration fails, is cancelled, or needs input, continue in Grafana. When it completes, review the enabled checks in Grafana before &lt;a href=&#34;#start-and-pause-monitoring&#34;&gt;starting monitoring&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If the request outcome is &lt;code&gt;unavailable&lt;/code&gt;, calibrate the saved Watcher in Grafana. An &lt;code&gt;error&lt;/code&gt; or &lt;code&gt;not-requested&lt;/code&gt; outcome returns exit code 4 and retains the Watcher identity. Inspect the reported failure and status; resolve any failed configuration stage with &lt;code&gt;update&lt;/code&gt;, then continue in Grafana. Do not repeat &lt;code&gt;create&lt;/code&gt;: a request error can leave calibration running.&lt;/p&gt;
&lt;h2 id=&#34;inspect-and-update-configuration&#34;&gt;Inspect and update configuration&lt;/h2&gt;
&lt;p&gt;To change an existing Watcher, follow these steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Find its resource name or ID:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx assistant watchers list&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Add &lt;code&gt;--archived&lt;/code&gt; to list archived Watchers. If a name matches several Watchers, use an ID.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Save its configuration to a file:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx assistant watchers get WATCHER -o yaml &amp;gt; watcher.yaml&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Edit the file, then apply the complete manifest:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx assistant watchers update WATCHER -f watcher.yaml&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;update&lt;/code&gt; and &lt;code&gt;resources push&lt;/code&gt; replace the modeled configuration. Omitted optional settings receive defaults, including disabled notification destinations. Start from an exported manifest to retain your existing choices. These operations preserve calibrated checks and learned state, and do not request calibration, start monitoring, or pause it. If an edit is rejected during calibration, wait for it to finish or cancel it in Grafana.&lt;/p&gt;
&lt;p&gt;If an apply reports a partial failure, changes may already be saved. Inspect the returned Watcher ID and failed stage, resolve the failure, and reapply with &lt;code&gt;update&lt;/code&gt; or &lt;code&gt;resources push&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Use &lt;code&gt;status&lt;/code&gt; for calibration, checks, and runtime observations; &lt;code&gt;get&lt;/code&gt; exports configuration only. A paused Watcher can retain an older health assessment.&lt;/p&gt;
&lt;p&gt;Use Grafana for custom automatic-recalibration schedules and other settings gcx cannot represent. gcx refuses configuration writes that would drop those settings.&lt;/p&gt;
&lt;h2 id=&#34;manage-configuration-files&#34;&gt;Manage configuration files&lt;/h2&gt;
&lt;p&gt;To store and reapply Watcher configuration, follow these steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Export the manifests:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx resources pull watchers -p ./watchers -o yaml&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Edit the files and validate them without writing to Grafana:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx resources push -p ./watchers --dry-run&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Review your changes, then apply them:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx resources push -p ./watchers&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;An unchanged apply sends no mutation unless you supply secret values. Push saves configuration only; calibrate new definitions in Grafana. Dry-run checks the manifest locally, so permissions, data source access, and other server checks still apply when you push.&lt;/p&gt;
&lt;h2 id=&#34;configure-slack-and-alerting-notifications&#34;&gt;Configure Slack and Alerting notifications&lt;/h2&gt;
&lt;p&gt;To select a Slack recipient and an Alerting notification policy tree, follow these steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Add the following under &lt;code&gt;spec&lt;/code&gt; in your complete Watcher manifest. Replace the example IDs and policy tree with your destination values:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;notifications:
  slack:
    enabled: true
    targetType: dm
    userId: U_EXAMPLE
    teamId: T_EXAMPLE
    severity: critical
  alerting:
    enabled: true
    severity: critical
    routingTree: example-policy-tree&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For a Slack channel, use &lt;code&gt;targetType: channel&lt;/code&gt; and &lt;code&gt;channelId&lt;/code&gt; instead of &lt;code&gt;userId&lt;/code&gt;. &lt;code&gt;teamId&lt;/code&gt; is optional. Enabled channels require a nonblank channel ID; direct messages require a nonblank user ID even when disabled.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Apply the complete manifest with &lt;code&gt;gcx assistant watchers update WATCHER -f watcher.yaml&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Verify the saved destinations with &lt;code&gt;gcx assistant watchers get WATCHER -o yaml&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Notification severity defaults to &lt;code&gt;warning-and-critical&lt;/code&gt;. Set &lt;code&gt;routingTree: &amp;quot;&amp;quot;&lt;/code&gt; to use the default notification policy tree. Manage notification policy trees and contact points in Grafana Alerting.&lt;/p&gt;
&lt;h2 id=&#34;supply-webhook-secrets&#34;&gt;Supply webhook secrets&lt;/h2&gt;
&lt;p&gt;Use &lt;code&gt;fromEnv&lt;/code&gt; or &lt;code&gt;fromFile&lt;/code&gt; to supply a secret, for example &lt;code&gt;url: { fromEnv: WATCHER_WEBHOOK_URL }&lt;/code&gt;. Exports use &lt;code&gt;{ preserve: true }&lt;/code&gt; for saved secrets; omitting a secret on update also preserves it. Use &lt;code&gt;{ clear: true }&lt;/code&gt; to remove one. You can&amp;rsquo;t use preserve markers when creating a Watcher.&lt;/p&gt;
&lt;p&gt;When supplying or clearing a webhook URL, also supply or clear every saved bearer token and signing secret. Keep resolved secrets out of manifests and version control.&lt;/p&gt;
&lt;h2 id=&#34;start-and-pause-monitoring&#34;&gt;Start and pause monitoring&lt;/h2&gt;
&lt;p&gt;After calibration completes with at least one enabled check, start your Watcher:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx assistant watchers start WATCHER&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Starting can immediately run a scan; event-only Watchers wait for their trigger. Both start and run can send configured notifications or launch investigations. If start fails, inspect &lt;code&gt;gcx assistant watchers status WATCHER&lt;/code&gt; before retrying: monitoring might already be active.&lt;/p&gt;
&lt;p&gt;To stop future scans, pause the Watcher:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx assistant watchers pause WATCHER&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Finish or cancel calibration in Grafana before pausing. An in-flight scan can still finish and send notifications or launch investigations.&lt;/p&gt;
&lt;h2 id=&#34;request-a-run-and-inspect-history&#34;&gt;Request a run and inspect history&lt;/h2&gt;
&lt;p&gt;Request a scan without changing the schedule, then inspect recent executions:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx assistant watchers run WATCHER -o json
gcx assistant watchers list-runs WATCHER --limit 20 -o json&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The run receipt reports acceptance, skipped work, or failure. Acceptance doesn&amp;rsquo;t mean the scan completed. Its &lt;code&gt;taskId&lt;/code&gt; can&amp;rsquo;t be matched to history IDs; don&amp;rsquo;t assume the newest execution belongs to your request. Running might require create permission in addition to write permission.&lt;/p&gt;
&lt;p&gt;History shows execution status separately from assessment. The default limit is 20, and the maximum is 100. &lt;code&gt;coverage.hasMore&lt;/code&gt; indicates additional retained history; results aren&amp;rsquo;t a snapshot of all past runs. For full run evidence, open the Watcher in Grafana.&lt;/p&gt;
&lt;h2 id=&#34;archive-and-recover-a-watcher&#34;&gt;Archive and recover a Watcher&lt;/h2&gt;
&lt;p&gt;Pause before archiving to retain the Watcher&amp;rsquo;s configuration and history:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx assistant watchers pause WATCHER
gcx assistant watchers archive WATCHER&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Archive only accepts a Watcher whose status is &lt;code&gt;paused&lt;/code&gt;; pause it first. If it is calibrating, finish or cancel calibration in Grafana before pausing. Keep other clients from starting it during this sequence: the pause check and archive aren&amp;rsquo;t atomic. Archiving can resolve active Grafana Alerting findings.&lt;/p&gt;
&lt;p&gt;Recover an archived Watcher without activating monitoring:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx assistant watchers unarchive WATCHER&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Review its status and automatic-stop deadline before starting again. Recovery retains that deadline. Archive recovery doesn&amp;rsquo;t restore a previous definition version.&lt;/p&gt;
&lt;h2 id=&#34;compare-definition-versions&#34;&gt;Compare definition versions&lt;/h2&gt;
&lt;p&gt;To inspect saved definitions before restoring one, follow these steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;List retained versions:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx assistant watchers list-versions WATCHER --limit 20 -o json&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Results contain one page. If &lt;code&gt;coverage.nextBeforeVersion&lt;/code&gt; is present, pass it as &lt;code&gt;--before-version&lt;/code&gt; to read the next page. Server retention can exclude older versions.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Read the definition you want to inspect:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx assistant watchers versions get WATCHER VERSION -o yaml&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Compare two definitions:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx assistant watchers versions diff WATCHER FROM_VERSION TO_VERSION -o json&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The diff compares definitions only. Add &lt;code&gt;--json path,operation&lt;/code&gt; to show changed paths and operations while retaining the compared versions and scope.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;restore-a-definition-version&#34;&gt;Restore a definition version&lt;/h2&gt;
&lt;p&gt;Restore creates a new current definition version. It requires a non-archived Watcher in &lt;code&gt;draft&lt;/code&gt;, &lt;code&gt;paused&lt;/code&gt;, or &lt;code&gt;ready&lt;/code&gt; state. It retains current notification actions and settings outside the definition; it doesn&amp;rsquo;t copy historical learned state.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Inspect the Watcher&amp;rsquo;s lifecycle and current version:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx assistant watchers status WATCHER -o json&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For a running Watcher, run &lt;code&gt;gcx assistant watchers pause WATCHER&lt;/code&gt; first. Finish or cancel calibration in Grafana before restoring.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Replace &lt;code&gt;CURRENT_VERSION&lt;/code&gt; with the version reported by &lt;code&gt;status&lt;/code&gt;, then restore the selected &lt;code&gt;VERSION&lt;/code&gt; and confirm:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx assistant watchers versions restore WATCHER VERSION --expected-current-version CURRENT_VERSION -o json&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;A stale guard is rejected. Inspect status and compare again before choosing a new guard.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The restored Watcher stays inactive and can become a draft that needs calibration. You can restore another version from that draft without pausing it. Review it in Grafana before starting monitoring. If the write outcome is unknown, inspect &lt;code&gt;status&lt;/code&gt; and &lt;code&gt;list-versions&lt;/code&gt; before retrying. A confirmed save followed by failed verification returns exit code 4; inspect the saved version instead of repeating the restore.&lt;/p&gt;
&lt;h2 id=&#34;delete-a-watcher&#34;&gt;Delete a Watcher&lt;/h2&gt;
&lt;p&gt;To remove a Watcher, run the following command and confirm deletion:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;gcx assistant watchers delete WATCHER&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Use &lt;code&gt;--force&lt;/code&gt; only when you want to skip confirmation.&lt;/p&gt;
]]></content><description>&lt;h1 id="manage-assistant-watchers">Manage Assistant Watchers&lt;/h1>
&lt;p>Use &lt;code>gcx&lt;/code> to create Watchers and keep their configuration in version control. &lt;strong>Watcher commands are experimental and require Grafana Cloud&lt;/strong>.&lt;/p>
&lt;h2 id="before-you-begin">Before you begin&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="../../configuration/">Configure a gcx context&lt;/a> for a Grafana Cloud stack with Assistant Watchers enabled.&lt;/li>
&lt;li>Make sure your identity can read and manage Watchers and access the data sources you want to monitor.&lt;/li>
&lt;/ul>
&lt;p>Commands use your selected context. Add &lt;code>--context CONTEXT&lt;/code> to select another context.&lt;/p></description></item></channel></rss>