Skip to content

Commit

Permalink
Merge pull request #2638 from codyrancher/dashboard-metrics
Browse files Browse the repository at this point in the history
Adding grafana graphs to the explorer index
  • Loading branch information
codyrancher authored Apr 14, 2021
2 parents 3075355 + 5ff458f commit 1e6c2af
Show file tree
Hide file tree
Showing 8 changed files with 716 additions and 33 deletions.
37 changes: 37 additions & 0 deletions assets/translations/en-us.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,21 @@ generic:
value: Value
yes: Yes
no: No
units:
time:
5s: 5s
10s: 10s
30s: 30s
1m: 1m
5m: 5m
15m: 15m
30m: 30m
1h: 1h
2h: 2h
6h: 6h
1d: 1d
7d: 7d
30d: 30d

locale:
en-us: English
Expand Down Expand Up @@ -824,6 +839,12 @@ clusterIndexPage:
label: Resource
date:
label: Date
clusterMetrics:
label: Cluster Metrics
etcdMetrics:
label: Etcd Metrics
k8sMetrics:
label: Kubernetes Components Metrics
gatekeeper:
buttonText: Configure Gatekeeper
disabled: OPA Gatekeeper is not configured.
Expand Down Expand Up @@ -875,6 +896,12 @@ detailText:
=1 {+ 1 more char}
other {+ {n, number} more chars}
}
etcdInfoBanner:
hasLeader: "Etcd has a leader:"
leaderChanges: "Number of leader changes:"
failedProposals: "Number of failed proposals:"

fleet:
cluster:
summary: Resource Summary
Expand Down Expand Up @@ -1006,6 +1033,16 @@ glance:
provider: Provider
version: Kubernetes Version

grafanaDashboard:
failedToLoad: Failed to load graph
reload: Reload

graphOptions:
detail: Detail
summary: Summary
refresh: Refresh
range: Range

hpa:
detail:
currentMetrics:
Expand Down
70 changes: 70 additions & 0 deletions components/DashboardMetrics.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<script>
import DashboardOptions from '@/components/DashboardOptions';
import GrafanaDashboard from '@/components/GrafanaDashboard';
import { mapGetters } from 'vuex';
export default {
components: { DashboardOptions, GrafanaDashboard },
props: {
detailUrl: {
type: String,
required: true,
},
summaryUrl: {
type: String,
required: true,
},
graphHeight: {
type: String,
required: true
}
},
data() {
return {
graphOptions: {
range: '5m', refreshRate: '30s', type: 'detail'
}
};
},
computed: {
...mapGetters(['prefs/theme']),
graphBackgroundColor() {
return this.theme === 'dark' ? '#2e3035' : '#f3f4f9';
},
theme() {
return this['prefs/theme'];
},
},
};
</script>

<template>
<div class="dashboard-graph">
<div class="graph-options mb-10">
<DashboardOptions v-model="graphOptions" />
</div>
<div class="info">
<slot />
</div>
<div class="graphs" :style="{height: graphHeight}">
<GrafanaDashboard
v-if="graphOptions.type === 'detail'"
class="col span-12 detail"
:background-color="graphBackgroundColor"
:theme="theme"
:refresh-rate="graphOptions.refreshRate"
:range="graphOptions.range"
:url="detailUrl"
/>
<GrafanaDashboard
v-else
class="col span-12 summary"
:background-color="graphBackgroundColor"
:theme="theme"
:refresh-rate="graphOptions.refreshRate"
:range="graphOptions.range"
:url="summaryUrl"
/>
</div>
</div>
</template>
127 changes: 127 additions & 0 deletions components/DashboardOptions.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
<script>
import ButtonGroup from '@/components/ButtonGroup';
import LabeledSelect from '@/components/form/LabeledSelect';
export default {
components: { ButtonGroup, LabeledSelect },
props: {
value: {
type: Object,
required: true,
}
},
data() {
return {
range: null,
rangeOptions: [
{
label: this.t('generic.units.time.5m'),
value: '5m',
},
{
label: this.t('generic.units.time.1h'),
value: '1h',
},
{
label: this.t('generic.units.time.6h'),
value: '6h',
},
{
label: this.t('generic.units.time.1d'),
value: '1d',
},
{
label: this.t('generic.units.time.7d'),
value: '7d',
},
{
label: this.t('generic.units.time.30d'),
value: '30d',
},
],
refreshOptions: [
{
label: this.t('generic.units.time.5s'),
value: '5s',
},
{
label: this.t('generic.units.time.10s'),
value: '10s',
},
{
label: this.t('generic.units.time.30s'),
value: '30s',
},
{
label: this.t('generic.units.time.1m'),
value: '1m',
},
{
label: this.t('generic.units.time.5m'),
value: '5m',
},
{
label: this.t('generic.units.time.15m'),
value: '15m',
},
{
label: this.t('generic.units.time.30m'),
value: '30m',
},
{
label: this.t('generic.units.time.1h'),
value: '1h',
},
{
label: this.t('generic.units.time.2h'),
value: '2h',
},
{
label: this.t('generic.units.time.1d'),
value: '1d',
}
],
detailSummaryOptions: [
{
label: this.t('graphOptions.detail'),
value: 'detail'
},
{
label: this.t('graphOptions.summary'),
value: 'summary'
}
]
};
}
};
</script>

<template>
<div class="graph-options">
<ButtonGroup v-model="value.type" :options="detailSummaryOptions" />
<div class="range-refresh">
<LabeledSelect v-model="value.range" :options="rangeOptions" :label="t('graphOptions.range')" />
<LabeledSelect v-model="value.refreshRate" :options="refreshOptions" :label="t('graphOptions.refresh')" />
</div>
</div>
</template>

<style lang='scss' scoped>
.graph-options {
&, .range-refresh {
display: flex;
flex-direction: row;
justify-content: flex-end;
}
& {
justify-content: space-between;
align-items: center;
}
.labeled-select {
width: 100px;
margin-left: 10px;
}
}
</style>
57 changes: 57 additions & 0 deletions components/EtcdInfoBanner.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<script>
import Banner from '@/components/Banner';
import Loading from '@/components/Loading';
import { mapGetters } from 'vuex';
import { hasLeader, leaderChanges, failedProposals } from '@/utils/grafana';
export default {
components: { Banner, Loading },
async fetch() {
const leader = await hasLeader(this.$store.dispatch, this.currentCluster.id);
this.hasLeader = leader ? this.t('generic.yes') : this.t('generic.no');
this.leaderChanges = await leaderChanges(this.$store.dispatch, this.currentCluster.id);
this.failedProposals = await failedProposals(this.$store.dispatch, this.currentCluster.id);
},
data() {
return {
hasLeader: this.t('generic.no'),
leaderChanges: 0,
failedProposals: 0
};
},
computed: { ...mapGetters(['currentCluster']) }
};
</script>

<template>
<Loading v-if="$fetchState.pending" />
<Banner v-else class="banner" color="info">
<div class="datum">
<label>{{ t('etcdInfoBanner.hasLeader') }}</label> {{ hasLeader }}
</div>
<div class="datum">
<label>{{ t('etcdInfoBanner.leaderChanges') }}</label> {{ leaderChanges }}
</div>
<div class="datum">
<label>{{ t('etcdInfoBanner.failedProposals') }}</label> {{ failedProposals }}
</div>
</Banner>
</template>

<style lang='scss' scoped>
.banner {
display: flex;
justify-content: space-evenly;
align-items: center;
.datum {
text-align: center;
}
& ::v-deep label {
color: var(--info);
}
}
</style>
Loading

0 comments on commit 1e6c2af

Please sign in to comment.