From 08203a060e94de08220bdbc9edb1fff6abb75b92 Mon Sep 17 00:00:00 2001
From: Darren Janeczek <38694490+darrenjaneczek@users.noreply.github.com>
Date: Thu, 11 Sep 2025 13:13:17 -0400
Subject: [PATCH] feat: NavTree menu entry for adaptive telemetry grafana cloud
apps (#109561)
* feat: NavTree menu entry for adaptive telemetry grafana cloud apps
* feat: 'adaptive-telemetry' icon added
---
packages/grafana-data/src/types/icon.ts | 1 +
pkg/services/navtree/models.go | 1 +
pkg/services/navtree/navtreeimpl/applinks.go | 31 +++++++++++++++++--
public/app/routes/routes.tsx | 4 +++
.../img/icons/unicons/adaptive-telemetry.svg | 1 +
5 files changed, 35 insertions(+), 3 deletions(-)
create mode 100644 public/img/icons/unicons/adaptive-telemetry.svg
diff --git a/packages/grafana-data/src/types/icon.ts b/packages/grafana-data/src/types/icon.ts
index 1f7cf51c2ee..b59fdeca75a 100644
--- a/packages/grafana-data/src/types/icon.ts
+++ b/packages/grafana-data/src/types/icon.ts
@@ -98,6 +98,7 @@ export const availableIconsIndex = {
'download-alt': true,
draggabledots: true,
drilldown: true,
+ 'adaptive-telemetry': true,
edit: true,
'ellipsis-v': true,
enter: true,
diff --git a/pkg/services/navtree/models.go b/pkg/services/navtree/models.go
index 250b3bf8717..51bbdf261b1 100644
--- a/pkg/services/navtree/models.go
+++ b/pkg/services/navtree/models.go
@@ -41,6 +41,7 @@ const (
NavIDDashboards = "dashboards/browse"
NavIDExplore = "explore"
NavIDDrilldown = "drilldown"
+ NavIDAdaptiveTelemetry = "adaptive-telemetry"
NavIDCfg = "cfg" // NavIDCfg is the id for org configuration navigation node
NavIDAlertsAndIncidents = "alerts-and-incidents"
NavIDTestingAndSynthetics = "testing-and-synthetics"
diff --git a/pkg/services/navtree/navtreeimpl/applinks.go b/pkg/services/navtree/navtreeimpl/applinks.go
index b54e679de9c..0cc24694b96 100644
--- a/pkg/services/navtree/navtreeimpl/applinks.go
+++ b/pkg/services/navtree/navtreeimpl/applinks.go
@@ -37,6 +37,8 @@ func (s *ServiceImpl) addAppLinks(treeRoot *navtree.NavTreeRoot, c *contextmodel
return false
}
+ enabledAccessibleAppPluginMap := make(map[string]*pluginstore.Plugin)
+
for _, plugin := range s.pluginStore.Plugins(c.Req.Context(), plugins.TypeApp) {
if !isPluginEnabled(plugin) {
continue
@@ -46,11 +48,20 @@ func (s *ServiceImpl) addAppLinks(treeRoot *navtree.NavTreeRoot, c *contextmodel
continue
}
+ enabledAccessibleAppPluginMap[plugin.ID] = &plugin
if appNode := s.processAppPlugin(plugin, c, treeRoot); appNode != nil {
appLinks = append(appLinks, appNode)
}
}
+ if adaptiveTelemetryPlugin := enabledAccessibleAppPluginMap["grafana-adaptivetelemetry-app"]; adaptiveTelemetryPlugin != nil {
+ if adaptiveTelemetrySection := treeRoot.FindById(navtree.NavIDAdaptiveTelemetry); adaptiveTelemetrySection != nil {
+ // If the adaptivetelemetry app is enabled, and the adaptiveTelemetrySection exists, then update the section to point to the plugin
+ adaptiveTelemetrySection.Url = s.cfg.AppSubURL + "/a/" + adaptiveTelemetryPlugin.ID
+ adaptiveTelemetrySection.PluginID = adaptiveTelemetryPlugin.ID
+ }
+ }
+
if len(appLinks) > 0 {
sort.SliceStable(appLinks, func(i, j int) bool {
return appLinks[i].Text < appLinks[j].Text
@@ -291,6 +302,19 @@ func (s *ServiceImpl) addPluginToSection(c *contextmodel.ReqContext, treeRoot *n
Children: []*navtree.NavLink{appLink},
Url: s.cfg.AppSubURL + "/testing-and-synthetics",
})
+ case navtree.NavIDAdaptiveTelemetry:
+ treeRoot.AddSection(&navtree.NavLink{
+ Text: "Adaptive Telemetry",
+ Id: navtree.NavIDAdaptiveTelemetry,
+ SubTitle: "Reduce noise, cut costs, and accelerate troubleshooting by intelligently ingesting only the telemetry data that matters most.",
+ Icon: "adaptive-telemetry",
+ SortWeight: navtree.WeightAIAndML + 1, // Place under "AI & Machine Learning"
+ Children: []*navtree.NavLink{appLink},
+ Url: "adaptive-telemetry",
+ // Use the icon URL from the first "Adaptive Telemetry" plugin in the list (they will all be the same)
+ Img: s.cfg.AppSubURL + plugin.Info.Logos.Large,
+ IsNew: true,
+ })
default:
s.log.Error("Plugin app nav id not found", "pluginId", plugin.ID, "navId", sectionID)
}
@@ -333,9 +357,10 @@ func (s *ServiceImpl) readNavigationSettings() {
"grafana-slo-app": {SectionID: navtree.NavIDAlertsAndIncidents, SortWeight: 7},
"grafana-cloud-link-app": {SectionID: navtree.NavIDCfgPlugins, SortWeight: 3},
"grafana-costmanagementui-app": {SectionID: navtree.NavIDCfg, Text: "Cost management"},
- "grafana-adaptive-metrics-app": {SectionID: navtree.NavIDCfg, Text: "Adaptive Metrics"},
- "grafana-adaptivelogs-app": {SectionID: navtree.NavIDCfg, Text: "Adaptive Logs"},
- "grafana-adaptivetraces-app": {SectionID: navtree.NavIDCfg, Text: "Adaptive Traces"},
+ "grafana-adaptive-metrics-app": {SectionID: navtree.NavIDAdaptiveTelemetry, SortWeight: 1, Text: "Adaptive Metrics", SubTitle: "Analyzes and reduces unused metrics and cardinality to help you focus on your most valuable performance data."},
+ "grafana-adaptivelogs-app": {SectionID: navtree.NavIDAdaptiveTelemetry, SortWeight: 2, Text: "Adaptive Logs", SubTitle: "Analyzes log patterns to drop repetitive lines and accelerate troubleshooting."},
+ "grafana-adaptivetraces-app": {SectionID: navtree.NavIDAdaptiveTelemetry, SortWeight: 3, Text: "Adaptive Traces", SubTitle: "Analyzes and retains the most valuable traces, providing the performance insights needed to resolve issues faster."},
+ "grafana-adaptiveprofiles-app": {SectionID: navtree.NavIDAdaptiveTelemetry, SortWeight: 4, Text: "Adaptive Profiles", SubTitle: "Analyzes application profiles to pinpoint the root cause of performance issues and accelerate resolution."},
"grafana-attributions-app": {SectionID: navtree.NavIDCfg, Text: "Attributions"},
"grafana-logvolumeexplorer-app": {SectionID: navtree.NavIDCfg, Text: "Log Volume Explorer"},
"grafana-easystart-app": {SectionID: navtree.NavIDRoot, SortWeight: navtree.WeightApps + 1, Text: "Connections", Icon: "adjust-circle"},
diff --git a/public/app/routes/routes.tsx b/public/app/routes/routes.tsx
index 334087cfbed..3767ed90322 100644
--- a/public/app/routes/routes.tsx
+++ b/public/app/routes/routes.tsx
@@ -187,6 +187,10 @@ export function getAppRoutes(): RouteDescriptor[] {
path: '/testing-and-synthetics',
component: () => ,
},
+ {
+ path: '/adaptive-telemetry',
+ component: () => ,
+ },
{
path: '/monitoring',
component: () => ,
diff --git a/public/img/icons/unicons/adaptive-telemetry.svg b/public/img/icons/unicons/adaptive-telemetry.svg
new file mode 100644
index 00000000000..557d011c86c
--- /dev/null
+++ b/public/img/icons/unicons/adaptive-telemetry.svg
@@ -0,0 +1 @@
+
\ No newline at end of file