Skip to content

Commit d44a9c1

Browse files
(status page) Add missing api key state
Add a special state for Kamon APM reporter that guides the user in case their API key is not configured or is invalid. Update Typescript and underscore to allow for modern dev practices.
1 parent 4b397cb commit d44a9c1

File tree

5 files changed

+71
-16
lines changed

5 files changed

+71
-16
lines changed

core/kamon-status-page/src/main/vue/package-lock.json

+3-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/kamon-status-page/src/main/vue/package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"dependencies": {
1111
"axios": "^0.21.1",
1212
"ts-option": "1.1.5",
13-
"underscore": "1.9.1",
13+
"underscore": "^1.9.1",
1414
"vue": "2.6.10",
1515
"vue-class-component": "7.0.2",
1616
"vue-property-decorator": "8.1.0",
@@ -19,15 +19,15 @@
1919
},
2020
"devDependencies": {
2121
"@fortawesome/fontawesome-free": "5.8.1",
22-
"@types/underscore": "1.8.14",
22+
"@types/underscore": "^1.8.14",
2323
"@vue/cli-plugin-typescript": "3.6.0",
2424
"@vue/cli-service": "3.6.0",
2525
"fstream": ">=1.0.12",
2626
"node-sass": "4.11.0",
2727
"sass": "^1.32.0",
2828
"sass-loader": "^7.1.0",
2929
"tar": ">=2.2.2",
30-
"typescript": "3.4.5",
30+
"typescript": "3.9.7",
3131
"vue-cli-plugin-vuetify": "~2.1.0",
3232
"vue-template-compiler": "2.6.10",
3333
"vuetify-loader": "^1.7.0"

core/kamon-status-page/src/main/vue/src/components/ModuleList.vue

+32-5
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,12 @@
1616
</div>
1717
</template>
1818

19-
<module-status-card v-for="reporter in reporterModules" :key="reporter.name" :module="reporter" />
19+
<module-status-card
20+
v-for="reporter in reporterModules"
21+
:key="reporter.name"
22+
:module="reporter"
23+
:is-missing-key="isMisconfiguredApmModule(reporter)"
24+
/>
2025
<div v-if="!hasApmModule" class="apm-suggestion">
2126
<a href="https://kamon.io/apm/?utm_source=kamon&utm_medium=status-page&utm_campaign=kamon-status" target="_blank">
2227
<module-status-card :isSuggestion="true" :module="apmModuleSuggestion" />
@@ -31,11 +36,17 @@
3136
</template>
3237

3338
<script lang="ts">
39+
import { Option } from 'ts-option'
3440
import { Component, Prop, Vue } from 'vue-property-decorator'
41+
3542
import {Module, ModuleKind} from '../api/StatusApi'
3643
import ModuleStatusCard from './ModuleStatusCard.vue'
3744
import StatusSection from './StatusSection.vue'
3845
46+
const VALID_API_KEY_PATTERN = /^[a-zA-Z0-9]{26}$/
47+
const KNOWN_APM_CLASSES = [
48+
'kamon.apm.KamonApm'
49+
]
3950
4051
@Component({
4152
components: {
@@ -45,6 +56,8 @@ import StatusSection from './StatusSection.vue'
4556
})
4657
export default class ModuleList extends Vue {
4758
@Prop() private modules!: Module[]
59+
@Prop({ required: true }) private config!: Option<any>
60+
4861
private apmModuleSuggestion: Module = {
4962
name: 'Kamon APM Reporter',
5063
description: 'See your metrics and trace data for free with a Starter account.',
@@ -79,15 +92,29 @@ export default class ModuleList extends Vue {
7992
}
8093
8194
get hasApmModule(): boolean {
82-
const knownApmClasses = [
83-
'kamon.apm.KamonApm'
84-
]
95+
return this.modules.some(m => KNOWN_APM_CLASSES.includes(m.clazz))
96+
}
97+
98+
get missingApmApiKey(): boolean {
99+
if (this.config.isEmpty) {
100+
return false
101+
}
85102
86-
return this.modules.some(m => knownApmClasses.includes(m.clazz))
103+
if (!this.hasApmModule) {
104+
return false
105+
}
106+
107+
const apiKey = this.config.get?.kamon?.apm?.['api-key']
108+
109+
return apiKey == null || !VALID_API_KEY_PATTERN.test(apiKey)
87110
}
88111
89112
private isReporter(module: Module): boolean {
90113
return [ModuleKind.Combined, ModuleKind.Span, ModuleKind.Metric].includes(module.kind)
91114
}
115+
116+
private isMisconfiguredApmModule(m: Module) {
117+
return KNOWN_APM_CLASSES.includes(m.clazz) && this.missingApmApiKey
118+
}
92119
}
93120
</script>

core/kamon-status-page/src/main/vue/src/components/ModuleStatusCard.vue

+28-4
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,24 @@
44
:indicator-icon="runStatus.icon"
55
:indicator-background-color="runStatus.color"
66
:indicator-color="runStatus.indicatorColor"
7-
:content-class="{ 'suggestion-card': isSuggestion }"
7+
:content-class="{ 'suggestion-card': isSuggestion, 'misconfigured-card': isMissingKey }"
88
>
99
<template #default>
1010
<div>
1111
<div class="text-label dark1--text">
1212
{{module.name}}
1313
</div>
1414
<div class="text-sublabel mt-1 dark3--text">
15-
{{module.description}}
15+
<span v-if="isMissingKey">
16+
Setting <strong>kamon.apm.api-key</strong> in <strong>application.conf</strong> invalid or missing
17+
</span>
18+
<span v-else>
19+
{{module.description}}
20+
</span>
1621
</div>
1722
</div>
1823
</template>
19-
<template #status v-if="!isSuggestion">
24+
<template #status v-if="!isSuggestion && !isMissingKey">
2025
<div
2126
class="module-status text-indicator px-2 py-1 rounded"
2227
:class="chipClasses"
@@ -29,6 +34,11 @@
2934
Connect APM
3035
</v-btn>
3136
</template>
37+
<template #action v-else-if="isMissingKey">
38+
<v-btn depressed color="warning" class="px-4 font-weight-bold" @click="showApmApiKey">
39+
Configure API Key
40+
</v-btn>
41+
</template>
3242
</status-card>
3343
</template>
3444

@@ -47,14 +57,17 @@ const isInstrumentationModule = (m: any): m is InstrumentationModule =>
4757
})
4858
export default class ModuleStatusCard extends Vue {
4959
@Prop({ default: false }) private isSuggestion!: boolean
60+
@Prop({ default: false }) private isMissingKey!: boolean
5061
@Prop() private module!: Module | InstrumentationModule
5162
5263
get started(): boolean {
5364
return isInstrumentationModule(this.module) ? this.module.active : this.module.started
5465
}
5566
5667
get status(): string {
57-
if (this.started) {
68+
if (this.isMissingKey) {
69+
return 'Not Configured'
70+
} else if (this.started) {
5871
return 'Enabled'
5972
} else if (this.module.enabled) {
6073
return 'Present'
@@ -68,6 +81,8 @@ export default class ModuleStatusCard extends Vue {
6881
return { message: 'suggested', color: 'primary', icon: 'fa-plug', indicatorColor: 'white' }
6982
} else if (!this.module.enabled) {
7083
return { message: 'disabled', color: 'error', icon: 'fa-stop-circle', indicatorColor: 'white' }
84+
} else if (this.isMissingKey) {
85+
return { message: 'not configured', color: 'warning', icon: 'fa-plug', indicatorColor: 'white'}
7186
} else {
7287
return this.started ?
7388
{ message: 'active', color: 'primary', icon: 'fa-check', indicatorColor: 'white' } :
@@ -84,6 +99,10 @@ export default class ModuleStatusCard extends Vue {
8499
return 'red4 error--text'
85100
}
86101
}
102+
103+
public showApmApiKey() {
104+
window.open('https://apm.kamon.io?envinfo=show')
105+
}
87106
}
88107
</script>
89108

@@ -92,4 +111,9 @@ export default class ModuleStatusCard extends Vue {
92111
border: 1px solid #3BC882 !important;
93112
background-color: #E3FFF1 !important;
94113
}
114+
115+
.misconfigured-card {
116+
border: 1px solid #FFCC00 !important;
117+
background-color: #FFF8E5 !important;
118+
}
95119
</style>

core/kamon-status-page/src/main/vue/src/views/Overview.vue

+5-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
</v-col>
1717

1818
<v-col cols="12" class="js-reporters">
19-
<module-list :modules="modules"/>
19+
<module-list :config="config" :modules="modules"/>
2020
</v-col>
2121

2222
<v-col cols="12" class="js-instrumentation">
@@ -107,6 +107,10 @@ export default class Overview extends Vue {
107107
return this.settings.map(s => s.environment)
108108
}
109109
110+
get config(): Option<any> {
111+
return this.settings.map(s => s.config)
112+
}
113+
110114
public mounted() {
111115
this.refreshData()
112116
}

0 commit comments

Comments
 (0)