<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Perses Blog - Community</title>
    <link>https://perses.dev/blog/category/community/</link>
    <description>News, release notes and stories from the Perses community.</description>
    <atom:link href="https://perses.dev/blog/category/community/rss.xml" rel="self" type="application/rss+xml"/>
    <language>en</language>
    <lastBuildDate>Wed, 18 Jun 2025 00:00:00 GMT</lastBuildDate>
    <image><url>https://perses.dev/assets/images/favicon.png</url><title>Perses Blog - Community</title><link>https://perses.dev/blog/category/community/</link></image>
    <item>
      <title>Introducing the Perses MCP Server</title>
      <link>https://perses.dev/blog/2025/06/18/introducing-the-perses-mcp-server/</link>
      <guid isPermaLink="true">https://perses.dev/blog/2025/06/18/introducing-the-perses-mcp-server/</guid>
      <pubDate>Wed, 18 Jun 2025 00:00:00 GMT</pubDate>
      <category>Community</category>
      <description>We&apos;re thrilled to introduce the Perses MCP Server, now available in public beta. This new tool empowers you to interact with your Perses instances using natural language, opening up a world of…</description>
      <content:encoded><![CDATA[
<p>We're thrilled to introduce the <strong>Perses MCP Server</strong>, now available in public beta. This new tool empowers you to interact with your Perses instances using natural language, opening up a world of possibilities for monitoring and visualization.</p>
<p>With the Perses MCP Server, users can use AI Agents to understand, query and interact with Perses APIs in a standardized and secure manner.</p>
<p>Imagine being able to prompt your favorite AI Agent with questions like:</p>
<ul>
<li>"How many dashboards are created in the last 5 days in project 'Test Project'?"</li>
<li>"What is the default datasource for project 'Test Project'?"
<ul>
<li>"Is this datasource in proxy mode? and what is the URL?"</li>
</ul>
</li>
<li>"Analyze this dashboard 'Dashboard A' in project 'Test Project'"
<ul>
<li>Suggest me some improvements to panels and PromQL queries in this dashboard</li>
</ul>
</li>
</ul>
<p>As you can see, the possibilities are endless. The Perses MCP Server allows you to interact with Perses in ways that were previously not possible.</p>
<!-- more -->
<picture>
  <img alt="Fallback image description" src="https://github.com/user-attachments/assets/416409df-9045-41f3-b10b-91df3020af1f">
</picture>
<p>This diagram visually represents how the Perses MCP Server acts as an intermediary between your AI Agent and the Perses Application.</p>
<h3 id="what-is-mcp-the-model-context-protocol-explained">What is MCP - The Model Context Protocol Explained</h3>
<p>You might be wondering what makes this all possible. The magic behind the scenes is the Model Context Protocol (MCP), an open standard pioneered by Anthropic that is quickly gaining industry-wide adoption.</p>
<p>MCP’s purpose is to create a universal language for AI agents to interact with the "outside world" that is, any data or system beyond their initial training data. This protocol enables AI to securely access real-time information and perform tasks by connecting to external APIs. In short, MCP provides a paved road for Large Language Models (LLMs) to interact with external systems like databases, APIs, and filesystems.</p>
<p>Major players like Google, Microsoft, and OpenAI have already committed to supporting MCP.</p>
<h3 id="how-to-use-the-perses-mcp-server">How to Use the Perses MCP Server</h3>
<p>Using the Perses MCP Server is simple and straightforward.</p>
<ol>
<li>Follow this <a href="https://github.com/perses/mcp-server/blob/main/README.md#usage">User Guide</a> to install and configure the MCP Server;</li>
<li><strong>Ask a Question</strong>: Pose a natural language question to your favorite AI agent, such as, "When was 'Dashboard A' in 'Project B' last updated?";</li>
<li><strong>Get an Answer</strong>: The MCP Server instantly gets to work, querying the Perses API and delivering the answer back to your AI agent in seconds.</li>
</ol>
<p>Check out this short demo to see it in action:</p>
<video controls>
  <source src="https://perses.dev/assets/images/blog/mcp-server/perses-mcp-server-demo.mp4" type="video/mp4">
  Your browser does not support the video tag.
</video>
<h3 id="getting-started-with-perses-mcp-server">Getting Started with Perses MCP Server</h3>
<p>Ready to dive in? Here are the resources you'll need:</p>
<ul>
<li><strong>Perses MCP Server GitHub Repository:</strong> Explore the code, read the documentation, and find the installation instructions <a href="https://github.com/perses/mcp-server">here</a>;</li>
<li><strong>Perses Official Website:</strong> Discover more about the Perses, its features, blog posts and documentation <a href="https://perses.dev/">here</a>.</li>
</ul>
<h3 id="whats-next">What's next?</h3>
<p>This public beta is just the beginning. Currently, the server supports read-only operations, allowing you to query the Perses API. Our roadmap includes adding write capabilities, which will enable you to use AI agents to create and update Perses resources like dashboards, projects, and datasources.</p>
<p>We are committed to an open development process and we welcome your feedback and contributions as we build these new features.</p>]]></content:encoded>
    </item>
    <item>
      <title>Composable Dashboards -  Lessons from building Perses Community Dashboards</title>
      <link>https://perses.dev/blog/2025/06/10/composable-dashboards----lessons-from-building-perses-community-dashboards/</link>
      <guid isPermaLink="true">https://perses.dev/blog/2025/06/10/composable-dashboards----lessons-from-building-perses-community-dashboards/</guid>
      <pubDate>Tue, 10 Jun 2025 00:00:00 GMT</pubDate>
      <category>Community</category>
      <description>Every CNCF User/Developer/Contributor has, at some point, to endure the frustration of trying to salvage an outdated dashboard, or adapting upstream YAML, only to get to the point of wondering why it…</description>
      <content:encoded><![CDATA[
<h2 id="why-we-keep-rewriting-the-same-dashboards">Why we keep rewriting the same dashboards</h2>
<p>Every CNCF User/Developer/Contributor has, at some point, to endure the frustration of trying to salvage an outdated dashboard, or adapting upstream YAML, only to get to the point of wondering why it doesn't work on their setup. This leads to a recurring pattern: everyone ends up rebuilding the same dashboards, over and over again, each slightly different.</p>
<p>The Mixins Dashboards helped bring about a sense of relief, as users now could use dashboards and alerts packaged together with the code they are deployed with. In theory, this promised consistency and easier integration. In practical terms, as the concept of mixins relies on Jsonnet, and even though it’s a suitable language for configuration management, it leads to a few issues:</p>
<ul>
<li>
<p>Jsonnet has a steep learning curve. It’s not a conventional Turing-complete programming language, and often makes it hard for downstream users of mixins to be able to do any sort of customization on their dashboards;</p>
</li>
<li>
<p>Mixin Jsonnet is completely detached from the actual application code. It was introduced as a way to maintain dashboarding config for code that you are deploying side by side, to ensure it never goes out of sync. However, many mixins are rarely updated, even when the code is - sometimes these are maintained out of the tree. And Jsonnet cannot use Go structs, so there is no automatic validation during code changes. Thus keeping mixins accurate and reliable demands a lot of effort.;</p>
</li>
<li>
<p>Adoption has also been uneven. A good example of this is kube-prometheus stack, built with Jsonnet, where many users bypass it entirely and only fetch the rendered YAML from that repository, then doing any sort of changes with tools like Kustomize instead. This undermines the original goal of reuse and standardization.</p>
</li>
</ul>
<p>The end result is, that despite the promise of reusable dashboards, the reality is there’s still not a widely used solution for automatic dashboards creation.</p>
<!-- more -->
<h2 id="perses-kubecon-eu-recap-maybe-theres-a-better-way-to-build-dashboards">Perses KubeCon EU Recap - Maybe there’s a better way to build Dashboards</h2>
<p>During <strong>KubeCon EU 2025</strong> in London, two of Perses’ core maintainers, Nicolas Takashi and Antoine Thébaud, shared how Perses is changing the way engineers develop and manage dashboards as code. Their talk covered the power of the Open Dashboard Model, how to use strongly typed code with the Perses Go SDK, and why this approach fits naturally into CI/CD pipelines using modern GitOps practices. If you didn’t get a chance to watch it live, you can watch the full session <a href="http://youtube.com/watch?v=7h70Olo5Uzk">here</a>.</p>
<p>They also mentioned the <strong>Community Dashboards</strong> Project, but didn’t have time to dive into it during the session. With that in mind is our belief that such an important topic deserves more space, and as so we bring this into live here.</p>
<h2 id="moving-away-from-rebuilding-the-same-dashboards-to-composable-dashboards">Moving away from rebuilding the same dashboards to composable dashboards</h2>
<p>With the limitations of mixins in mind, the Perses community decided to take a different path. Since Perses is written in Go, with both its configuration and plugins defined using Go structs, it presents an opportunity to design dashboards in a more efficient and structured way. This approach takes full advantage of the Go structs imported from Perses, with its robust SDK that has the methods and constructs to build dashboards. This then ensures consistency with the core project, safe versioning, both for the dashboard data model and each individual panel plugins, and type-safe dashboard construction and customization.</p>
<p>Introducing the <a href="https://github.com/perses/community-dashboards">community-dashboards</a> repository. Maintained by community contributors, it offers the following dashboards in type-safe modular Go SDK based Dashboards as Code:</p>
<p><img src="https://perses.dev/assets/images/blog/community-dashboards/perses-dashboards-overview.png" alt="Dashboard overview"></p>
<p>The goal of the community-dashboards library isn't just to provide ready-to-use YAML dashboards (though you can use them as-is), but to empower users to import the project as a Go module in their downstream configuration, generate tailored subsets of dashboards, and customize or extend them to meet specific needs (similar to what mixins originally intended).</p>
<p>A core strength of the Perses Community Dashboards is its modular, reusable panel library. These panels—such as Go CPU Usage and Memory Consumption—serve as building blocks that can be composed into new dashboards. Instead of starting from scratch, users can leverage these community-maintained components to quickly build dashboards suited to their applications and workloads.</p>
<p>This approach also lowers the barrier to achieving consistency across dashboards. By reusing the same patterns to build and display common metrics, dashboards remain aligned across teams and services. This makes it easier to compare environments, onboard new engineers, and scale observability practices—without reinventing the wheel.</p>
<p><img src="https://perses.dev/assets/images/blog/community-dashboards/perses-dashboards-am.png" alt="AM overview"></p>
<h2 id="how-to-build-composable-dashboards-a-practical-example">How to build composable dashboards - a practical example</h2>
<p>Here we have an example of how to define a panel of Time Series type below. More detailed info about the available option for Time Series Panels can be found <a href="https://pkg.go.dev/github.com/perses/plugins/timeserieschart">here</a> and <a href="https://pkg.go.dev/github.com/perses/promql-builder">PromQLBuilder</a>.</p>
<pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0"><code class="language-go"><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">// Define your panel</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">func</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> CPUUsage</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">datasourceName</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> string</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">labelMatchers</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> ...*</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">labels</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">Matcher</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">panelgroup</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">Option</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">	return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> panelgroup.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">AddPanel</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"CPU Usage"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">		panel.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">Description</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"Shows the CPU usage of the component."</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">),</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">		timeSeriesPanel.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">Chart</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">			timeSeriesPanel.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">WithYAxis</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">timeSeriesPanel</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">YAxis</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">{</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">				Format: </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">&#x26;</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">commonSdk</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">Format</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">{</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">					Unit: </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">string</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(commonSdk.DecimalUnit),</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">				},</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">			}),</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">			timeSeriesPanel.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">WithLegend</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">timeSeriesPanel</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">Legend</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">{</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">				Position: timeSeriesPanel.BottomPosition,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">				Mode:     timeSeriesPanel.TableMode,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">				Values:   []</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">commonSdk</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">Calculation</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">{commonSdk.LastCalculation},</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">			}),</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">			timeSeriesPanel.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">WithVisual</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">timeSeriesPanel</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">Visual</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">{</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">				Display:      timeSeriesPanel.LineDisplay,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">				ConnectNulls: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">false</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">				LineWidth:    </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">0.25</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">				AreaOpacity:  </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">0.5</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">				Palette:      </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">timeSeriesPanel</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">Palette</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">{Mode: timeSeriesPanel.AutoMode},</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">			}),</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">		),</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">		panel.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">AddQuery</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">			query.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">PromQL</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">				promql.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">SetLabelMatchersV2</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">					promqlbuilder.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">Rate</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">						matrix.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">New</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">							vector.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">New</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">								vector.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">WithMetricName</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"process_cpu_seconds_total"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">),</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">							),</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">							matrix.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">WithRangeAsVariable</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"$__rate_interval"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">),</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">						),</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">					),</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">					labelMatchers,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">				).</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">Pretty</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">),</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">				dashboards.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">AddQueryDataSource</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(datasourceName),</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">				query.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">SeriesNameFormat</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"{{pod}}"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">),</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">			),</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">		),</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">	)</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span></code></pre>
<p>Next after you have your first panel, it’s time to add it to a dashboard - here’s how to add to a dashboard named <code>Workload / Overview</code>:</p>
<pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0"><code class="language-go"><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">// Use the panel in a dashboard</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">func</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> withResources</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">datasource</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> string</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">clusterLabelMatcher</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> *</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">labels</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">Matcher</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">dashboard</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">Option</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">	labelMatchersToUse </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">:=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> []</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">*</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">labels</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">Matcher</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">{</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">		promql.JobVarV2,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">	}</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">	labelMatchersToUse </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> append</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(labelMatchersToUse, clusterLabelMatcher)</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">	return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> dashboard.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">AddPanelGroup</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"CPU Usage"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">		panelgroup.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">PanelsPerLine</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">),</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">		panelgroup.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">PanelHeight</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">10</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">),</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">		panelsGostats.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">CPUUsage</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(datasource, labelMatchersToUse</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">...</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">),</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">	)</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">// Build the dashboard and add the time series panel withResources</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">func</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> BuildWorkloadOverview</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">project</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> string</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">datasource</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> string</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">clusterLabelName</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> string</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">dashboards</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">DashboardResult</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">	clusterLabelMatcher </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">:=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> dashboards.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">GetClusterLabelMatcherV2</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(clusterLabelName)</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">	return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> dashboards.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">NewDashboardResult</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">		dashboard.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">New</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"workload-overview"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">			dashboard.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">ProjectName</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(project),</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">			dashboard.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">Name</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"Workload / Overview"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">),</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">			dashboard.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">AddVariable</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"job"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">				listvariable.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">List</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">					labelvalues.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">PrometheusLabelValues</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"job"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">						labelvalues.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">Matchers</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"workload_build_info{}"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">),</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">						dashboards.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">AddVariableDatasource</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(datasource),</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">					),</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">					listvariable.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">DisplayName</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"job"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">),</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">				),</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">			),</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">			withResources</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(datasource, clusterLabelMatcher),</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">		),</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">	).</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">Component</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">"workload"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">)</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span></code></pre>
<p>For more on the SDK please check <a href="https://pkg.go.dev/github.com/perses/perses/go-sdk">perses/go-sdk</a>, and <a href="https://pkg.go.dev/github.com/perses/community-dashboards">community-dashboards</a>.</p>
<h2 id="beyond-copy-pasting-cleaner-and-smarter-way-to-building-dashboards">Beyond Copy-Pasting - Cleaner and Smarter way to building Dashboards</h2>
<p>Going back to the idea of copy-pasting raw YAML or JSON, although it might seem quicker, it leads to painful maintenance over time. The Go SDK offers a better path:</p>
<ul>
<li><strong>Type safety</strong> - You get compile-time feedback if something is wrong. No more mystery errors buried in JSON blobs.</li>
<li><strong>Reusability</strong> - Define a panel once and reuse it wherever you want. Avoid duplication and drift.</li>
<li><strong>Maintainability</strong> -  When a panel definition needs an update, you can do it in one place and apply it across all dashboards.</li>
<li><strong>CI/CD friendly</strong> - Code is easier to version, review, and test. It fits naturally into modern GitOps workflows.</li>
</ul>
<p>Combining the use of panel libraries and the SDK, you get a flexible and scalable way to manage dashboards, while saving time, reducing errors, and staying consistent across your observability stack. This allows a community of dashboards users to have their lives made easier with these features.</p>
<p>Also considering the most commonly used dashboard across platforms and teams, like <strong>Kubernetes</strong>, <strong>Prometheus</strong> and exporters like <strong>Node Exporter</strong>, <strong>Blackbox Exporter</strong>, also projects like <strong>Thanos</strong> dashboards as it tends to be a power duo within the Prometheus ecosystem, we have from the get go some core dashboards that will help you in the long term in your observability journey.</p>
<h2 id="next-steps-for-the-community-dashboards">Next Steps for the Community Dashboards</h2>
<p>We’re committed to expanding support for more CNCF and other OSS projects while continuing to enhance the existing panel libraries. By adding more features and improving the quality of reusable panels, we enable users to gain deeper insights from their dashboards because the faster you can pinpoint an issue in your telemetry data, the better.</p>
<p>Also, we aim to ensure proper documentation for all dashboards. Whether you're importing full dashboards or using panel libraries as building blocks, we want to make the process as seamless as possible. That means clear, well-commented code and guidance, so modularity is not only guaranteed but also easy to work with, without needing to dig through the entire codebase.</p>
<p>Ultimately, this is a community effort, and we invite everyone to help grow this project. So if you have a dashboard you’ve rewritten more than once, or any mixin dashboard you use, but want to ensure it becomes modular, easily used and want to increase adoption of it. Whether it’s opening an issue or submitting a contribution, all help is moving forward so we can all, very soon, stop rebuilding the same dashboards.</p>
<p>Let’s stop duplicating efforts and start building shared observability standards!</p>]]></content:encoded>
    </item>
  </channel>
</rss>
