Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
c9e83f6
feat: create grafana component
bornast Mar 16, 2026
1df2135
docs: add grafana aws account hardcoded value comment
bornast Mar 16, 2026
ff2d228
refactor: provider config value extraction
bornast Mar 17, 2026
02cb734
feat: remove tags prop from grafana builder and component
bornast Mar 17, 2026
452c85c
refactor: rename grafana resources
bornast Mar 18, 2026
fd465d2
feat: grafana addDashboard builder method
bornast Mar 18, 2026
37e5dde
refactor: config naming
bornast Mar 18, 2026
60d26c2
Merge branch 'feat/grafana-comp' into feat/grafana-dashboards
bornast Mar 18, 2026
509db81
feat: add name public prop to grafana component
bornast Mar 18, 2026
fd8dd9d
Merge branch 'feat/grafana-comp' into feat/grafana-dashboards
bornast Mar 18, 2026
29e7167
feat: introduce grafana connections
bornast Mar 19, 2026
9aced94
refactor: remove unnecessary lines
bornast Mar 19, 2026
b766efe
refactor: method signatures
bornast Mar 19, 2026
99376d5
feat: make grafana props readonly
bornast Mar 19, 2026
50398f2
Merge branch 'feat/grafana-comp' into feat/grafana-dashboards
bornast Mar 19, 2026
631ded8
feat: add name prop to grafana component
bornast Mar 19, 2026
8cec815
refactor: method signatures
bornast Mar 25, 2026
1626551
refactor: method signatures
bornast Mar 25, 2026
075cad6
Merge branch 'feat/grafana-comp' into feat/grafana-dashboards
bornast Mar 26, 2026
fa0dd95
feat: generic dashboard builder
bornast Mar 27, 2026
d07403c
Merge branch 'master' into feat/grafana-dashboards
bornast Mar 27, 2026
6a58b75
Merge branch 'master' into feat/grafana-dashboards
bornast Mar 30, 2026
fde5f48
refactor: dashboard build configuration
bornast Mar 30, 2026
21a9b46
refactor: dashboard builder
bornast Mar 30, 2026
4d46c9b
feat: add dashboard builder default configuration
bornast Mar 30, 2026
813775e
refactor: panel export type
bornast Mar 30, 2026
a389874
refactor: panel types
bornast Mar 30, 2026
0c6d123
refactor: rename prometheusNamespace to ampNamespace
bornast Mar 30, 2026
e522d6f
refactor: panel types
bornast Mar 30, 2026
36dac57
Merge branch 'master' into feat/grafana-dashboards
bornast Mar 30, 2026
3049a67
refactor: error msg
bornast Mar 30, 2026
518e77c
refactor: rename connection and dashboard creation methods
bornast Mar 31, 2026
7f56ddf
Merge branch 'master' into feat/grafana-dashboards
bornast Mar 31, 2026
5598b23
feat: add grafana folderName parameter
bornast Mar 31, 2026
75a00ff
feat: make amp plugin installation optional
bornast Mar 31, 2026
ec0eddf
feat: make xray connection plugin installation optional
bornast Mar 31, 2026
5b5c231
feat: add dataSourceName prop
bornast Mar 31, 2026
46e116c
feat: add slo dashboard builder method
bornast Mar 31, 2026
f899b71
refactor: data source prop type
bornast Mar 31, 2026
a94815a
refactor: grafana dashboard name
bornast Mar 31, 2026
3a98fe0
refactor: rename slo dashboard
bornast Mar 31, 2026
9bf81b4
refactor: grafana builder error messages
bornast Mar 31, 2026
e7245e2
feat: introduce withTitle method inside grafana dashboard builder
bornast Apr 1, 2026
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
36 changes: 36 additions & 0 deletions src/components/grafana/builder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import * as pulumi from '@pulumi/pulumi';
import { Grafana } from './grafana';
import { GrafanaDashboard } from './dashboards/types';

export class GrafanaBuilder {
private name: string;
private prometheusConfig?: Grafana.PrometheusConfig;
private dashboardConfigs: GrafanaDashboard.DashboardConfig[] = [];

constructor(name: string) {
this.name = name;
}

public withPrometheus(config: Grafana.PrometheusConfig): this {
this.prometheusConfig = config;

return this;
}

public addDashboard(config: GrafanaDashboard.DashboardConfig): this {
this.dashboardConfigs.push(config);

return this;
}

public build(opts: pulumi.ComponentResourceOptions = {}): Grafana {
return new Grafana(
this.name,
{
prometheusConfig: this.prometheusConfig,
dashboards: this.dashboardConfigs,
},
opts,
);
}
}
35 changes: 18 additions & 17 deletions src/components/grafana/dashboards/panels.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Grafana } from './types';
import * as pulumi from '@pulumi/pulumi';
import { GrafanaDashboard } from './types';

const percentageFieldConfig = {
unit: 'percent',
Expand All @@ -8,10 +9,10 @@ const percentageFieldConfig = {

export function createStatPercentagePanel(
title: string,
position: Grafana.Panel.Position,
dataSource: string,
metric: Grafana.Metric,
): Grafana.Panel {
position: GrafanaDashboard.PanelPosition,
dataSource: pulumi.Input<string>,
metric: GrafanaDashboard.Metric,
): GrafanaDashboard.Panel {
return {
title,
gridPos: position,
Expand Down Expand Up @@ -41,10 +42,10 @@ export function createStatPercentagePanel(

export function createTimeSeriesPercentagePanel(
title: string,
position: Grafana.Panel.Position,
dataSource: string,
metric: Grafana.Metric,
): Grafana.Panel {
position: GrafanaDashboard.PanelPosition,
dataSource: pulumi.Input<string>,
metric: GrafanaDashboard.Metric,
): GrafanaDashboard.Panel {
return createTimeSeriesPanel(
title,
position,
Expand All @@ -58,13 +59,13 @@ export function createTimeSeriesPercentagePanel(

export function createTimeSeriesPanel(
title: string,
position: Grafana.Panel.Position,
dataSource: string,
metric: Grafana.Metric,
position: GrafanaDashboard.PanelPosition,
dataSource: pulumi.Input<string>,
metric: GrafanaDashboard.Metric,
unit?: string,
min?: number,
max?: number,
): Grafana.Panel {
): GrafanaDashboard.Panel {
return {
title,
type: 'timeseries',
Expand Down Expand Up @@ -96,10 +97,10 @@ export function createTimeSeriesPanel(

export function createBurnRatePanel(
title: string,
position: Grafana.Panel.Position,
dataSource: string,
metric: Grafana.Metric,
): Grafana.Panel {
position: GrafanaDashboard.PanelPosition,
dataSource: pulumi.Input<string>,
metric: GrafanaDashboard.Metric,
): GrafanaDashboard.Panel {
return {
type: 'stat',
title,
Expand Down
54 changes: 29 additions & 25 deletions src/components/grafana/dashboards/types.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,27 @@
import * as pulumi from '@pulumi/pulumi';
import * as grafana from '@pulumiverse/grafana';

// TODO: Should we prefix all namespaces with `Studion`
export namespace Grafana {
// TODO: Create SLO abstraction that enables configuring:
// - panels (long-window SLI, long-window error budget)
// - alerts (long-window burn, short-window burn)
export type Threshold = {
value: number | null;
color: string;
};
export type Metric = {
label: string;
query: string;
thresholds: Threshold[];
// TODO: Create SLO abstraction that enables configuring:
// - panels (long-window SLI, long-window error budget)
// - alerts (long-window burn, short-window burn)
export namespace GrafanaDashboard {
export type DataSources = {
Comment thread
bornast marked this conversation as resolved.
Outdated
prometheus?: pulumi.Output<string>;
};

export interface DashboardConfig {
Comment thread
bornast marked this conversation as resolved.
Outdated
createResource(dataSources: DataSources): grafana.oss.Dashboard;
}

export type Args = {
title: pulumi.Input<string>;
provider: pulumi.Input<grafana.Provider>;
tags: pulumi.Input<pulumi.Input<string>[]>;
};

export type Panel = {
title: string;
gridPos: Panel.Position;
gridPos: PanelPosition;
type: string;
datasource: string;
datasource: pulumi.Input<string>;
targets: {
expr: string;
legendFormat: string;
Expand Down Expand Up @@ -62,12 +57,21 @@ export namespace Grafana {
};
};

export namespace Panel {
export type Position = {
x: number;
y: number;
w: number;
h: number;
};
}
export type PanelPosition = {
Comment thread
bornast marked this conversation as resolved.
Outdated
x: number;
y: number;
w: number;
h: number;
};

export type Threshold = {
value: number | null;
color: string;
};

export type Metric = {
label: string;
query: string;
thresholds: Threshold[];
};
}
Loading