Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ require (
github.com/open-telemetry/opentelemetry-operator v0.135.0
github.com/openshift/api v3.9.0+incompatible // PINNED: newer versions remove console/v1alpha1 API needed for OpenShift <4.17 compatibility
github.com/operator-framework/api v0.38.0
github.com/perses/perses v0.53.0-rc.0
github.com/perses/plugins/prometheus v0.57.0-rc.0
github.com/perses/plugins/table v0.11.0-rc.0
github.com/perses/plugins/timeserieschart v0.12.0-rc.0
github.com/perses/perses v0.53.0
github.com/perses/plugins/prometheus v0.57.0
github.com/perses/plugins/table v0.11.0
github.com/perses/plugins/timeserieschart v0.12.0
github.com/pkg/errors v0.9.1
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.87.0
github.com/prometheus/common v0.67.5
Expand Down Expand Up @@ -121,7 +121,7 @@ require (
github.com/novln/docker-parser v1.0.0 // indirect
github.com/oklog/ulid v1.3.1 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/perses/common v0.30.1 // indirect
github.com/perses/common v0.30.2 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus-community/prom-label-proxy v0.12.1 // indirect
github.com/prometheus/alertmanager v0.29.0 // indirect
Expand Down
20 changes: 10 additions & 10 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -382,16 +382,16 @@ github.com/operator-framework/operator-lib v0.18.0 h1:6OaWemt/CuyrjFMkLyk4O8Vj4C
github.com/operator-framework/operator-lib v0.18.0/go.mod h1:EWS6xGYBcMn04wj81j0bluAYbFHl3cJcar++poQMzqE=
github.com/ovh/go-ovh v1.9.0 h1:6K8VoL3BYjVV3In9tPJUdT7qMx9h0GExN9EXx1r2kKE=
github.com/ovh/go-ovh v1.9.0/go.mod h1:cTVDnl94z4tl8pP1uZ/8jlVxntjSIf09bNcQ5TJSC7c=
github.com/perses/common v0.30.1 h1:XjCHCrBOyXacDA+fa1pzlq+pNiPazTj4anUhbYGU0ho=
github.com/perses/common v0.30.1/go.mod h1:DFtur1QPah2/ChXbKKhw7djYdwNgz27s5fPKpiK0Xao=
github.com/perses/perses v0.53.0-rc.0 h1:f3V1j6EqnKyXUY0mNt4Zp/T6+5U/5SjtCzLHxj9sJDQ=
github.com/perses/perses v0.53.0-rc.0/go.mod h1:q+gB4M2yT//cO6GlCjhOTJLDoSrqtkMLul72Z0WOueI=
github.com/perses/plugins/prometheus v0.57.0-rc.0 h1:0yHyYBEEUfTKsdVtNpKGUlhyGFt/1IJYVlXRo6Bpp7M=
github.com/perses/plugins/prometheus v0.57.0-rc.0/go.mod h1:zZ6DVOB8f434iGZa77IwkXiphowiSfQWytzvteet98E=
github.com/perses/plugins/table v0.11.0-rc.0 h1:KEkKuuzijWbey+kxP7EoMCz2Rd28BoPLI8YqdYSXAsk=
github.com/perses/plugins/table v0.11.0-rc.0/go.mod h1:iVRHt4KUJ0EFwd7HL3meFN0n83bpk5obNliqoqF/yJk=
github.com/perses/plugins/timeserieschart v0.12.0-rc.0 h1:2P4DkFI4rtKV57UGzRfBDopCkg0j+Rcj47hYtrPXjIM=
github.com/perses/plugins/timeserieschart v0.12.0-rc.0/go.mod h1:3n7/E843eManujbGDqShioFkelLRFLvYmRIvupxBero=
github.com/perses/common v0.30.2 h1:RAiVxUpX76lTCb4X7pfcXSvYdXQmZwKi4oDKAEO//u0=
github.com/perses/common v0.30.2/go.mod h1:DFtur1QPah2/ChXbKKhw7djYdwNgz27s5fPKpiK0Xao=
github.com/perses/perses v0.53.0 h1:gh0m/OE3yTG4jCkseORuT3B1qAL3VlsnBckJSbpFjPs=
github.com/perses/perses v0.53.0/go.mod h1:HsCfkI+EZta2UEDCFa//HUyLRY0Z0fElJkpAWdARbGs=
github.com/perses/plugins/prometheus v0.57.0 h1:Be6mVgcwiPXk5CK6P/RW38AJdBHB+7p3q+w9KzXTF30=
github.com/perses/plugins/prometheus v0.57.0/go.mod h1:7yAwPMsHyhl1rdnnK6SzIuL7Gy+elJUbR5GHoJJD2rQ=
github.com/perses/plugins/table v0.11.0 h1:VnIc50JVocuQvTAWLhHfzHcUbMuCgSWdE70ewxfWYik=
github.com/perses/plugins/table v0.11.0/go.mod h1:R6CthZqzTLbh0pfWYna6SAueBXIHiWG3uTGW4O5J6Ws=
github.com/perses/plugins/timeserieschart v0.12.0 h1:cQ0T9RboPp8mUD2YZBRosDVnwouTpQCBu3XJzh7JRC8=
github.com/perses/plugins/timeserieschart v0.12.0/go.mod h1:X0815gg7xpnmWw5Lzse3EEtEMGR6gdHGieVbt0W7DSc=
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
Expand Down
224 changes: 92 additions & 132 deletions pkg/controllers/uiplugin/accelerators.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
package uiplugin

import (
"encoding/json"

"github.com/perses/perses/go-sdk/common"
"github.com/perses/perses/go-sdk/dashboard"
"github.com/perses/perses/go-sdk/panel"
panelgroup "github.com/perses/perses/go-sdk/panel-group"
listvariable "github.com/perses/perses/go-sdk/variable/list-variable"
"github.com/perses/perses/pkg/model/api/v1/variable"
"github.com/perses/plugins/prometheus/sdk/go/query"
labelvalues "github.com/perses/plugins/prometheus/sdk/go/variable/label-values"
timeseries "github.com/perses/plugins/timeserieschart/sdk/go"
persesv1alpha2 "github.com/rhobs/perses-operator/api/v1alpha2"
persesv1 "github.com/rhobs/perses/pkg/model/api/v1"
"github.com/rhobs/perses/pkg/model/api/v1/common"
"github.com/rhobs/perses/pkg/model/api/v1/dashboard"
"github.com/rhobs/perses/pkg/model/api/v1/variable"
persescommon "github.com/rhobs/perses/pkg/model/api/v1/common"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/ptr"
)
Expand All @@ -26,11 +35,11 @@ func newAcceleratorsDatasource(namespace string) *persesv1alpha2.PersesDatasourc
Spec: persesv1alpha2.DatasourceSpec{
Config: persesv1alpha2.Datasource{
DatasourceSpec: persesv1.DatasourceSpec{
Display: &common.Display{
Name: "acceelerators datasource",
Display: &persescommon.Display{
Name: "Accelerators Datasource",
},
Default: true,
Plugin: common.Plugin{
Plugin: persescommon.Plugin{
Kind: "PrometheusDatasource",
Spec: map[string]interface{}{
"proxy": map[string]interface{}{
Expand Down Expand Up @@ -59,7 +68,81 @@ func newAcceleratorsDatasource(namespace string) *persesv1alpha2.PersesDatasourc
}
}

func newAcceleratorsDashboard(namespace string) *persesv1alpha2.PersesDashboard {
func acceleratorPanel(panelName, targetMetric string) panelgroup.Option {
return panelgroup.AddPanel(panelName,
timeseries.Chart(
timeseries.WithLegend(timeseries.Legend{
Mode: timeseries.ListMode,
Position: timeseries.BottomPosition,
Values: []common.Calculation{},
}),
timeseries.WithVisual(timeseries.Visual{
AreaOpacity: 1,
ConnectNulls: false,
Display: timeseries.LineDisplay,
LineWidth: 0.25,
Stack: timeseries.AllStack,
}),
timeseries.WithYAxis(timeseries.YAxis{
Format: &common.Format{
Unit: ptr.To(string(common.DecimalUnit)),
},
Min: 0,
}),
),
panel.AddQuery(
query.PromQL(targetMetric,
query.SeriesNameFormat("{{vendor_id}}"),
),
),
)
}

func buildAcceleratorsDashboard() (dashboard.Builder, error) {
return dashboard.New("accelerators-dashboard",
dashboard.Name("Accelerators common metrics"),
dashboard.AddVariable("cluster",
listvariable.List(
listvariable.DisplayName("Cluster"),
listvariable.Hidden(false),
listvariable.AllowAllValue(false),
listvariable.AllowMultiple(false),
listvariable.SortingBy(variable.SortAlphabeticalAsc),
labelvalues.PrometheusLabelValues("cluster",
labelvalues.Matchers("up{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\"}"),
),
),
),
dashboard.AddPanelGroup("Accelerators",
panelgroup.PanelsPerLine(2),
acceleratorPanel("GPU Utilization", "accelerator_gpu_utilization"),
acceleratorPanel("Memory Used Bytes", "accelerator_memory_used_bytes"),
acceleratorPanel("Memory Total Bytes", "accelerator_memory_total_bytes"),
acceleratorPanel("Power Usage (Watts)", "accelerator_power_usage_watts"),
acceleratorPanel("Temperature (Celsius)", "accelerator_temperature_celsius"),
acceleratorPanel("SM Clock (Hertz)", "accelerator_sm_clock_hertz"),
acceleratorPanel("Memory Clock (Hertz)", "accelerator_memory_clock_hertz"),
),
)
}

func newAcceleratorsDashboard(namespace string) (*persesv1alpha2.PersesDashboard, error) {
builder, err := buildAcceleratorsDashboard()
if err != nil {
return nil, err
}

// Workaround because of type conflict between Perses plugin types and Perses fork in rhobs org
rhobsDashboard := persesv1.Dashboard{}
bytes, err := json.Marshal(builder.Dashboard)
if err != nil {
return nil, err
}
err = rhobsDashboard.UnmarshalJSON(bytes)
if err != nil {
return nil, err
}

return &persesv1alpha2.PersesDashboard{
TypeMeta: metav1.TypeMeta{
APIVersion: persesv1alpha2.GroupVersion.String(),
Expand All @@ -74,131 +157,8 @@ func newAcceleratorsDashboard(namespace string) *persesv1alpha2.PersesDashboard
},
Spec: persesv1alpha2.PersesDashboardSpec{
Config: persesv1alpha2.Dashboard{
DashboardSpec: persesv1.DashboardSpec{
Display: &common.Display{
Name: "Accelerators common metrics",
},
Variables: []dashboard.Variable{
{
Kind: variable.KindList,
Spec: &dashboard.ListVariableSpec{
Name: "cluster",
ListSpec: variable.ListSpec{
Display: &variable.Display{
Hidden: false,
},
AllowAllValue: false,
AllowMultiple: false,
Sort: ptr.To(variable.SortAlphabeticalAsc),
Plugin: common.Plugin{
Kind: "PrometheusLabelValuesVariable",
Spec: map[string]interface{}{
"labelName": "cluster",
"matchers": []interface{}{
"up{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\"}",
},
},
},
},
},
},
},
Panels: map[string]*persesv1.Panel{
"0_0": getPanel("GPU Utilization", "accelerator_gpu_utilization"),
"0_1": getPanel("Memory Used Bytes", "accelerator_memory_used_bytes"),
"0_2": getPanel("Memory Total Bytes", "accelerator_memory_total_bytes"),
"0_3": getPanel("Power Usage (Watts)", "accelerator_power_usage_watts"),
"0_4": getPanel("Temperature (Celsius)", "accelerator_temperature_celsius"),
"0_5": getPanel("SM Clock (Hertz)", "accelerator_sm_clock_hertz"),
"0_6": getPanel("Memory Clock (Hertz)", "accelerator_memory_clock_hertz"),
},
Layouts: []dashboard.Layout{
{
Kind: dashboard.KindGridLayout,
Spec: dashboard.GridLayoutSpec{
Display: &dashboard.GridLayoutDisplay{
Title: "Accelerators",
Collapse: &dashboard.GridLayoutCollapse{
Open: true,
},
},
Items: []dashboard.GridItem{
getGridItem(0, 0, "#/spec/panels/0_0"),
getGridItem(12, 0, "#/spec/panels/0_1"),
getGridItem(0, 7, "#/spec/panels/0_2"),
getGridItem(12, 7, "#/spec/panels/0_3"),
getGridItem(0, 14, "#/spec/panels/0_4"),
getGridItem(12, 14, "#/spec/panels/0_5"),
getGridItem(0, 21, "#/spec/panels/0_6"),
},
},
},
},
},
DashboardSpec: rhobsDashboard.Spec,
},
},
}
}

func getPanel(panelName, targetMetric string) *persesv1.Panel {
return &persesv1.Panel{
Kind: "Panel",
Spec: persesv1.PanelSpec{
Display: &persesv1.PanelDisplay{
Name: panelName,
},
Plugin: common.Plugin{
Kind: "TimeSeriesChart",
Spec: map[string]interface{}{
"legend": map[string]interface{}{
"mode": "list",
"position": "bottom",
"values": []interface{}{}, // Empty array
},
"visual": map[string]interface{}{
"areaOpacity": 1,
"connectNulls": false,
"display": "line",
"lineWidth": 0.25,
"stack": "all",
},
"yAxis": map[string]interface{}{
"format": map[string]interface{}{
"unit": "decimal",
},
"min": 0,
},
},
},
Queries: []persesv1.Query{
{
Kind: "TimeSeriesQuery",
Spec: persesv1.QuerySpec{
Plugin: common.Plugin{
Kind: "PrometheusTimeSeriesQuery",
Spec: map[string]interface{}{
"datasource": map[string]interface{}{
"kind": "PrometheusDatasource",
},
"query": targetMetric,
"seriesNameFormat": "{{vendor_id}}",
},
},
},
},
},
},
}
}

func getGridItem(xPos, yPos int, ref string) dashboard.GridItem {
return dashboard.GridItem{
X: xPos,
Y: yPos,
Width: 12,
Height: 7,
Content: &common.JSONRef{
Ref: ref,
},
}
}, nil
}
8 changes: 7 additions & 1 deletion pkg/controllers/uiplugin/components.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,15 @@ func pluginComponentReconcilers(plugin *uiv1alpha1.UIPlugin, pluginInfo UIPlugin
reconciler.NewOptionalUpdater(newClusterRoleBinding(namespace, persesServiceAccountName, "perses-cr", persesServiceAccountName+"-perses-cr"), plugin, persesEnabled),
reconciler.NewOptionalUpdater(newPerses(namespace, pluginInfo.PersesImage), plugin, persesEnabled),
reconciler.NewOptionalUpdater(newAcceleratorsDatasource(namespace), plugin, persesEnabled),
reconciler.NewOptionalUpdater(newAcceleratorsDashboard(namespace), plugin, persesEnabled),
)

acceleratorsDashboard, err := newAcceleratorsDashboard(namespace)
if err != nil {
logger.Error(err, "Cannot build Accelerators dashboard")
} else {
components = append(components, reconciler.NewOptionalUpdater(acceleratorsDashboard, plugin, persesEnabled))
}

apmDashboard, err := newAPMDashboard(namespace)
if err != nil {
logger.Error(err, "Cannot build APM dashboard")
Expand Down