aboutsummaryrefslogtreecommitdiff
path: root/kamon-status/src
diff options
context:
space:
mode:
Diffstat (limited to 'kamon-status/src')
-rw-r--r--kamon-status/src/App.vue72
-rw-r--r--kamon-status/src/api/StatusApi.ts40
-rw-r--r--kamon-status/src/assets/logo.pngbin6849 -> 0 bytes
-rw-r--r--kamon-status/src/assets/logo.svg145
-rw-r--r--kamon-status/src/components/HelloWorld.vue2
-rw-r--r--kamon-status/src/components/StatusCard.vue79
-rw-r--r--kamon-status/src/main.ts2
-rw-r--r--kamon-status/src/router.ts6
-rw-r--r--kamon-status/src/styles/main.scss12
-rw-r--r--kamon-status/src/views/Home.vue18
-rw-r--r--kamon-status/src/views/Overview.vue97
11 files changed, 429 insertions, 44 deletions
diff --git a/kamon-status/src/App.vue b/kamon-status/src/App.vue
index f300d4b4..88938081 100644
--- a/kamon-status/src/App.vue
+++ b/kamon-status/src/App.vue
@@ -1,29 +1,67 @@
<template>
<div id="app">
- <div id="nav">
- <router-link to="/">Home</router-link> |
- <router-link to="/about">About</router-link>
+ <div class="header w-100 mb-5 sticky-top">
+ <div class="container h-100">
+ <div class="row h-100 justify-content-between">
+ <div class="col-auto h-100">
+ <img class="py-3 h-100 img-fluid" src="./assets/logo.svg" alt="">
+ </div>
+
+ <div class="col-auto navigation">
+ <router-link to="/">
+ <div class="navigation-link">
+ Overview
+ </div>
+ </router-link>
+ <router-link to="/">
+ <div class="navigation-link">
+ Metrics
+ </div>
+ </router-link>
+ </div>
+ </div>
+ </div>
</div>
+
<router-view/>
</div>
+
</template>
<style lang="scss">
-#app {
- font-family: 'Avenir', Helvetica, Arial, sans-serif;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
- text-align: center;
- color: #2c3e50;
-}
-#nav {
- padding: 30px;
- a {
- font-weight: bold;
- color: #2c3e50;
- &.router-link-exact-active {
- color: #42b983;
+
+$header-height: 70px;
+
+.header {
+ height: $header-height;
+ background-color: white;
+ box-shadow: 0 5px 9px 1px rgba(0,0,0,0.1);
+
+ .navigation {
+ line-height: $header-height;
+
+ .navigation-link, a {
+ display: inline-block;
+ padding: 0 0.5rem;
+ text-transform: uppercase;
+ text-decoration: none;
+ color: #b3b3b3;
+
+ &:hover {
+ color: #888888;
+ }
}
}
}
+
+// #nav {
+// padding: 30px;
+// a {
+// font-weight: bold;
+// color: #2c3e50;
+// &.router-link-exact-active {
+// color: #42b983;
+// }
+// }
+// }
</style>
diff --git a/kamon-status/src/api/StatusApi.ts b/kamon-status/src/api/StatusApi.ts
index 540c1c53..7f18b2ed 100644
--- a/kamon-status/src/api/StatusApi.ts
+++ b/kamon-status/src/api/StatusApi.ts
@@ -7,35 +7,65 @@ export interface Environment {
tags: { [key: string]: string }
}
-export interface BaseInfo {
+export interface Config {
version: string
environment: Environment
config: any
}
+export enum ModuleKind {
+ Combined = "combined",
+ Metric = "metric",
+ Span = "span",
+ Plain = "plain",
+ Unknown = "unknown"
+}
+
export interface Module {
name: string
description: string
+ kind: ModuleKind
enabled: boolean
started: boolean
}
+export interface MetricInfo {
+ name: string
+ type: string
+ tags: { [key: string ]: string }
+}
+
export interface ModuleRegistryStatus {
modules: Array<Module>
}
+export interface MetricRegistryStatus {
+ metrics: Array<MetricInfo>
+}
+
export class StatusApi {
- public baseInfo(): Promise<BaseInfo> {
- return axios.get("/status/base-info").then(response => {
- return response.data as BaseInfo
+ public static configStatus(): Promise<Config> {
+ return axios.get("/status/config").then(response => {
+ const config = JSON.parse(response.data.config)
+ return {
+ version: response.data.version,
+ environment: response.data.environment,
+ config
+ }
})
}
- public moduleRegistryStatus(): Promise<ModuleRegistryStatus> {
+ public static moduleRegistryStatus(): Promise<ModuleRegistryStatus> {
return axios.get("/status/modules").then(response => {
return response.data as ModuleRegistryStatus
})
}
+
+ public static metricRegistryStatus(): Promise<MetricRegistryStatus> {
+ return axios.get("/status/metrics").then(response => {
+ return response.data as MetricRegistryStatus
+ })
+ }
} \ No newline at end of file
diff --git a/kamon-status/src/assets/logo.png b/kamon-status/src/assets/logo.png
deleted file mode 100644
index f3d2503f..00000000
--- a/kamon-status/src/assets/logo.png
+++ /dev/null
Binary files differ
diff --git a/kamon-status/src/assets/logo.svg b/kamon-status/src/assets/logo.svg
new file mode 100644
index 00000000..96b29425
--- /dev/null
+++ b/kamon-status/src/assets/logo.svg
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ id="Layer_1"
+ x="0px"
+ y="0px"
+ viewBox="0 0 1529.6959 283.96277"
+ xml:space="preserve"
+ sodipodi:docname="logo.svg"
+ inkscape:version="0.92.3 (2405546, 2018-03-11)"
+ width="1529.6959"
+ height="283.96277"><metadata
+ id="metadata923"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+ id="defs921" /><sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="2560"
+ inkscape:window-height="1415"
+ id="namedview919"
+ showgrid="false"
+ inkscape:zoom="0.98958333"
+ inkscape:cx="1158.9481"
+ inkscape:cy="121.48356"
+ inkscape:window-x="1920"
+ inkscape:window-y="0"
+ inkscape:window-maximized="0"
+ inkscape:current-layer="text950"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0" />
+<style
+ type="text/css"
+ id="style900">
+ .st0{fill:#3A493E;}
+ .st1{fill:#B3B3B3;}
+ .st2{fill:url(#XMLID_15_);}
+ .st3{fill:#14C441;}
+</style>
+
+<g
+ transform="matrix(0.99986889,0,0,0.99986889,0.18871224,0)"
+ id="XMLID_903_-5"
+ style="display:inline;fill:#616161;fill-opacity:1"><path
+ style="fill:#616161;fill-opacity:1"
+ d="m 388.3,82.3 v 62.3 l 34.9,-40 h 34 l -38.9,41.7 39.3,66.7 h -34 l -20,-37 c -3.6,-6.4 -7.2,-9.6 -10.8,-9.6 -3,0.6 -4.5,2.6 -4.5,5.5 v 41 H 360 V 68.4 h 14.7 c 7.5,0 13.6,6.4 13.6,13.9 z"
+ class="st0"
+ id="XMLID_914_-7"
+ inkscape:connector-curvature="0" /><path
+ style="fill:#616161;fill-opacity:1"
+ d="m 492.9,129.9 h -28.3 c 3.4,-20.8 18.1,-31 44,-31 31,0 46.8,10.2 47.4,31 v 38.3 c 0,31 -18.7,44.8 -49.1,47 -27,2.1 -45.7,-10.4 -45.7,-35.3 0.6,-27 20.2,-34.2 48.7,-37 12.1,-1.5 18.3,-5.1 18.3,-11.3 -0.6,-6.4 -6.6,-9.6 -18.3,-9.6 -10,0 -15.5,2.5 -17,7.9 z m 35.7,36.9 v -10.4 c -6.6,2.8 -14.2,5.1 -22.5,6.8 -11.3,2.1 -17,7.4 -17,15.7 0.6,8.9 5.3,13.2 14.2,13.2 15.7,0 25.3,-9.3 25.3,-25.3 z"
+ class="st0"
+ id="XMLID_911_-4"
+ inkscape:connector-curvature="0" /><path
+ style="fill:#616161;fill-opacity:1"
+ d="M 598.3,141.1 V 213 h -28.7 v -66.1 c 0,-32.1 16.2,-48 48.2,-48 14.5,0 25.5,3.2 33.6,9.6 8.1,-6.2 19.1,-9.1 33.6,-9.1 32.1,0 48,15.9 47.8,48 v 66.1 h -14.7 c -9.3,-0.6 -14,-5.1 -14,-14 v -57.8 c -0.6,-11.7 -7,-17.4 -19.6,-17.4 -12.5,0 -18.9,5.7 -19.1,17.4 V 213 H 637 v -71.8 c -0.6,-11.7 -7,-17.4 -19.6,-17.4 -12.6,0 -18.9,5.6 -19.1,17.3 z"
+ class="st0"
+ id="XMLID_909_-1"
+ inkscape:connector-curvature="0" /><path
+ style="fill:#616161;fill-opacity:1"
+ d="m 850.6,157.3 c 0,38.7 -17.2,58.2 -51.2,58.2 -34,0 -51,-19.6 -51,-58.2 0,-39.1 17,-58.4 51,-58.4 34,0 51.2,19.3 51.2,58.4 z m -73.6,0 c 0.2,21.9 7.6,32.9 22.1,32.9 14.5,0 21.7,-11.5 21.9,-33.8 0,-21.9 -7.2,-32.7 -21.7,-32.7 -14.8,0 -22.3,11.3 -22.3,33.6 z"
+ class="st0"
+ id="XMLID_906_-8"
+ inkscape:connector-curvature="0" /><path
+ style="fill:#616161;fill-opacity:1"
+ d="m 945.5,213 c -9.3,-0.6 -14,-5.1 -14,-14 v -57.8 c -0.6,-11.7 -7,-17.4 -19.6,-17.4 -12.6,0 -18.9,5.7 -19.1,17.4 V 213 h -28.7 v -66.1 c 0,-32.1 16.2,-48 48.2,-48 32.1,0 47.8,15.9 47.6,48 V 213 Z"
+ class="st0"
+ id="XMLID_904_-5"
+ inkscape:connector-curvature="0" /></g><g
+ transform="matrix(0.99986889,0,0,0.99986889,0.18871224,0)"
+ style="display:inline"
+ id="XMLID_899_-9"><path
+ style="fill:#dadada;fill-opacity:1"
+ d="m 153.7,244 36.5,38 c 1.2,1.2 3.1,2 5,2 h 89.5 c 5.2,0 8.3,-4.7 5.2,-8.1 l -83,-102.5 c -1.8,-2 -5.2,-1.9 -6.9,0.1 L 153.4,238 c -1.6,1.8 -1.4,4.2 0.3,6 z"
+ class="st1"
+ id="XMLID_902_-7"
+ inkscape:connector-curvature="0" /><linearGradient
+ xlink:href="#XMLID_15_-2"
+ y2="-214.94597"
+ x2="63.891499"
+ y1="198.12531"
+ x1="63.891499"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient936"><stop
+ id="stop1003-5"
+ style="stop-color:#145643"
+ offset="0" /><stop
+ id="stop1005-3"
+ style="stop-color:#14C441"
+ offset="1" /></linearGradient><path
+ style="fill:#199053;fill-opacity:1"
+ d="M 77,12.8 C 69.8,4.7 60.2,0 50.1,0 32.8,0 17.5,13.6 12.7,33.4 5.9,62 1.8,91.2 0.5,120.6 v 0 l 9.8,13.4 c 17.5,24.1 47.9,25.2 66.7,4.5 2.8,-2.3 5.4,-4.9 7.8,-7.8 L 127.4,79.2 C 127.3,79.2 79.5,15 77,12.8 Z"
+ class="st2"
+ id="XMLID_901_-8"
+ inkscape:connector-curvature="0" /><path
+ d="m 284.6,0 h -73.3 c -12.9,0 -24.8,5.9 -31.7,15.7 l -52.4,63.5 -42.6,51.5 c -2.4,2.9 -5,5.4 -7.8,7.8 C 58,159.2 27.6,158.1 10.1,134 L 0.3,120.6 v 0 0 0 c -1.4,30.8 0.2,61.7 4.9,92.2 0,0.1 0,0.1 0,0.2 0.4,2.3 0.7,4.7 1.1,7 0.1,0.4 0.1,0.8 0.2,1.2 0.3,2 0.7,4.1 1.1,6.1 0.1,0.5 0.2,1 0.3,1.5 0.4,2 0.8,3.9 1.2,5.9 0.1,0.5 0.2,0.9 0.3,1.4 0.5,2.2 0.9,4.4 1.4,6.6 0,0.2 0.1,0.4 0.1,0.5 4.9,22.3 20.9,38.4 39.9,40.5 0.2,0 0.3,0.1 0.5,0.1 1.3,0.1 2.5,0.2 3.8,0.2 0,0 0.1,0 0.1,0 v 0 c 32.3,0 50.7,-18.2 59.9,-30.8 L 291.7,11.8 C 295.4,6.7 291.4,0 284.6,0 Z"
+ class="st3"
+ id="XMLID_900_-8"
+ inkscape:connector-curvature="0"
+ style="fill:#34cc5b;fill-opacity:1" /><g
+ aria-label="STATUS"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:118.62699127px;line-height:125%;font-family:Montserrat;-inkscape-font-specification:'Montserrat, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#b3b3b3;fill-opacity:1;stroke:none;stroke-width:2.96567488px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ id="text950"><path
+ d="m 1039.2985,138.07737 q -6.3722,0 -10.4952,2.62381 -4.1232,2.6238 -4.1232,7.99636 0,5.24764 4.1232,8.12133 4.123,2.74875 17.4919,5.99726 13.494,3.24854 20.2409,9.12086 6.8719,5.87234 6.8719,17.36714 0,11.36984 -8.6211,18.49161 -8.6209,7.12177 -22.6147,7.12177 -20.4909,0 -36.3588,-14.11859 l 9.2459,-11.11996 q 13.2442,11.49479 27.4877,11.49479 7.1219,0 11.245,-2.99864 4.248,-3.12358 4.248,-8.12133 0,-5.12266 -3.9981,-7.87142 -3.8733,-2.8737 -13.494,-5.12268 -9.6207,-2.37392 -14.6184,-4.24807 -4.9978,-1.9991 -8.8711,-5.12267 -7.7466,-5.87235 -7.7466,-17.99184 0,-12.11952 8.7461,-18.61657 8.8711,-6.62198 21.8654,-6.62198 8.3711,0 16.6174,2.74875 8.2462,2.74874 14.2435,7.74648 l -7.8714,11.11996 q -3.8733,-3.49842 -10.4952,-5.74741 -6.6221,-2.24896 -13.1191,-2.24896 z"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:118.62699127px;font-family:Montserrat;-inkscape-font-specification:'Montserrat, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#b3b3b3;stroke-width:3.12358332px"
+ id="path952"
+ inkscape:connector-curvature="0" /><path
+ d="m 1119.4196,140.07645 v 73.84152 h -14.7434 v -73.84152 h -26.4878 v -13.49387 h 67.7192 v 13.49387 z"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:118.62699127px;font-family:Montserrat;-inkscape-font-specification:'Montserrat, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#b3b3b3;stroke-width:3.12358332px"
+ id="path954"
+ inkscape:connector-curvature="0" /><path
+ d="m 1160.1512,194.05197 -8.7461,19.866 h -15.7429 l 38.4825,-87.33539 h 15.7429 l 38.4826,87.33539 h -15.7427 l -8.7462,-19.866 z m 37.7329,-13.61882 -15.8679,-35.98368 -15.8677,35.98368 z"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:118.62699127px;font-family:Montserrat;-inkscape-font-specification:'Montserrat, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#b3b3b3;stroke-width:3.12358332px"
+ id="path956"
+ inkscape:connector-curvature="0" /><path
+ d="m 1258.5795,140.07645 v 73.84152 h -14.7433 v -73.84152 h -26.488 v -13.49387 h 67.7193 v 13.49387 z"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:118.62699127px;font-family:Montserrat;-inkscape-font-specification:'Montserrat, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#b3b3b3;stroke-width:3.12358332px"
+ id="path958"
+ inkscape:connector-curvature="0" /><path
+ d="m 1315.2932,193.92703 q 5.9972,6.99683 16.2426,6.99683 10.2455,0 16.2426,-6.99683 5.9973,-6.99684 5.9973,-18.99139 v -48.35306 h 14.7434 v 48.97779 q 0,18.86643 -10.3703,29.11179 -10.3704,10.12039 -26.613,10.12039 -16.2426,0 -26.6129,-10.12039 -10.3703,-10.24536 -10.3703,-29.11179 v -48.97779 h 14.7433 v 48.35306 q 0,11.99455 5.9973,18.99139 z"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:118.62699127px;font-family:Montserrat;-inkscape-font-specification:'Montserrat, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#b3b3b3;stroke-width:3.12358332px"
+ id="path960"
+ inkscape:connector-curvature="0" /><path
+ d="m 1407.7291,138.07737 q -6.3721,0 -10.4954,2.62381 -4.1231,2.6238 -4.1231,7.99636 0,5.24764 4.1231,8.12133 4.1233,2.74875 17.4922,5.99726 13.4938,3.24854 20.2408,9.12086 6.8718,5.87234 6.8718,17.36714 0,11.36984 -8.621,18.49161 -8.6211,7.12177 -22.6148,7.12177 -20.4906,0 -36.3584,-14.11859 l 9.2457,-11.11996 q 13.2439,11.49479 27.4876,11.49479 7.1218,0 11.2448,-2.99864 4.2481,-3.12358 4.2481,-8.12133 0,-5.12266 -3.9981,-7.87142 -3.8733,-2.8737 -13.4941,-5.12268 -9.6204,-2.37392 -14.6182,-4.24807 -4.9978,-1.9991 -8.8709,-5.12267 -7.7466,-5.87235 -7.7466,-17.99184 0,-12.11952 8.7461,-18.61657 8.8709,-6.62198 21.865,-6.62198 8.3713,0 16.6174,2.74875 8.2464,2.74874 14.2437,7.74648 l -7.8714,11.11996 q -3.8734,-3.49842 -10.4954,-5.74741 -6.6218,-2.24896 -13.1189,-2.24896 z"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:118.62699127px;font-family:Montserrat;-inkscape-font-specification:'Montserrat, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#b3b3b3;stroke-width:3.12358332px"
+ id="path962"
+ inkscape:connector-curvature="0" /></g></g></svg> \ No newline at end of file
diff --git a/kamon-status/src/components/HelloWorld.vue b/kamon-status/src/components/HelloWorld.vue
index d9e77ef3..af340a46 100644
--- a/kamon-status/src/components/HelloWorld.vue
+++ b/kamon-status/src/components/HelloWorld.vue
@@ -39,7 +39,7 @@ export default class HelloWorld extends Vue {
private mounted() {
console.log("I'm mounting the thing")
- axios.get("/status/base-config").then(result => {
+ axios.get("/status/config").then(result => {
console.log("GOT A RESULT", result.data)
})
}
diff --git a/kamon-status/src/components/StatusCard.vue b/kamon-status/src/components/StatusCard.vue
new file mode 100644
index 00000000..05047a19
--- /dev/null
+++ b/kamon-status/src/components/StatusCard.vue
@@ -0,0 +1,79 @@
+<template>
+ <div class="outer">
+ <div class="py-2 px-3 heading text-uppercase">
+ {{ statusInfo.heading }}
+ </div>
+ <hr>
+ <div class="px-3 py-2">
+ <div class="message" :class="messageStatusClass">
+ {{ statusInfo.message }}
+ </div>
+ <div class="caption">
+ {{ statusInfo.caption }}
+ </div>
+ </div>
+ </div>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue } from 'vue-property-decorator'
+import axios from 'axios'
+
+export enum Status {
+ Healthy,
+ Critical,
+ Unknown
+}
+
+export interface StatusInfo {
+ heading: string
+ message: string
+ caption?: string
+ status: Status
+}
+
+@Component
+export default class StatusCard extends Vue {
+ @Prop() private statusInfo!: StatusInfo
+
+ get messageStatusClass(): string[] {
+ if(this.statusInfo != null && this.statusInfo.status != Status.Unknown) {
+ return this.statusInfo.status == Status.Healthy ? ['healthy'] : ['critical']
+ } else {
+ return []
+ }
+ }
+}
+</script>
+
+<!-- Add "scoped" attribute to limit CSS to this component only -->
+<style scoped lang="scss">
+.outer {
+ background-color: white;
+ box-shadow: 0 2px 9px 1px rgba(0, 0, 0, 0.1);
+
+ .heading {
+ font-size: 0.9rem;
+ color: #a5a5a5;
+ }
+
+ .message {
+ color: #868686;
+ font-weight: 600;
+ font-size: 1.5rem;
+ }
+
+ .caption {
+ color: #a5a5a5;
+ }
+
+ .critical {
+ color: #ff6e6b;
+ }
+}
+
+hr {
+ margin: 1px;
+ border-color: #f3f3f3;
+}
+</style>
diff --git a/kamon-status/src/main.ts b/kamon-status/src/main.ts
index afd50249..0be7bece 100644
--- a/kamon-status/src/main.ts
+++ b/kamon-status/src/main.ts
@@ -1,6 +1,8 @@
import Vue from 'vue';
import App from './App.vue';
import router from './router';
+import 'bootstrap/dist/css/bootstrap.min.css';
+import './styles/main.scss';
Vue.config.productionTip = false;
diff --git a/kamon-status/src/router.ts b/kamon-status/src/router.ts
index e540d9a4..03d07eae 100644
--- a/kamon-status/src/router.ts
+++ b/kamon-status/src/router.ts
@@ -1,6 +1,6 @@
import Vue from 'vue';
import Router from 'vue-router';
-import Home from './views/Home.vue';
+import Overview from './views/Overview.vue';
Vue.use(Router);
@@ -8,8 +8,8 @@ export default new Router({
routes: [
{
path: '/',
- name: 'home',
- component: Home,
+ name: 'overview',
+ component: Overview,
},
{
path: '/about',
diff --git a/kamon-status/src/styles/main.scss b/kamon-status/src/styles/main.scss
new file mode 100644
index 00000000..8483e81b
--- /dev/null
+++ b/kamon-status/src/styles/main.scss
@@ -0,0 +1,12 @@
+body {
+ background-color: #f7f7f7;
+ font-size: 16px;
+ color: #616161;
+ font-family: 'Open Sans', Helvetica, Arial, sans-serif;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+h1, h2, h3 {
+ font-weight: 300;
+} \ No newline at end of file
diff --git a/kamon-status/src/views/Home.vue b/kamon-status/src/views/Home.vue
deleted file mode 100644
index 2187e5c9..00000000
--- a/kamon-status/src/views/Home.vue
+++ /dev/null
@@ -1,18 +0,0 @@
-<template>
- <div class="home">
- <img alt="Vue logo" src="../assets/logo.png">
- <HelloWorld msg="Welcome to Your Vue.js + TypeScript App"/>
- </div>
-</template>
-
-<script lang="ts">
-import { Component, Vue } from 'vue-property-decorator';
-import HelloWorld from '@/components/HelloWorld.vue'; // @ is an alias to /src
-
-@Component({
- components: {
- HelloWorld,
- },
-})
-export default class Home extends Vue {}
-</script>
diff --git a/kamon-status/src/views/Overview.vue b/kamon-status/src/views/Overview.vue
new file mode 100644
index 00000000..e0802eb7
--- /dev/null
+++ b/kamon-status/src/views/Overview.vue
@@ -0,0 +1,97 @@
+<template>
+ <div class="container">
+ <div class="row">
+ <div class="col-12 pb-3">
+ <h2>Overview</h2>
+ </div>
+ <div class="col-6 col-md-4 p-2">
+ <status-card :statusInfo="instrumentationStatus"></status-card>
+ </div>
+ <div class="col-6 col-md-4 p-2">
+ <status-card :statusInfo="reporterStatus"></status-card>
+ </div>
+ <div class="col-6 col-md-4 p-2">
+ <status-card :statusInfo="metricsStatus"></status-card>
+ </div>
+
+ </div>
+ </div>
+</template>
+
+<script lang="ts">
+import { Component, Vue } from 'vue-property-decorator'
+import {Option, none, some} from 'ts-option'
+import StatusCard, {StatusInfo, Status} from '../components/StatusCard.vue'
+import {StatusApi, Config, ModuleRegistryStatus, ModuleKind, MetricRegistryStatus, Module} from '../api/StatusApi'
+
+interface ComponentStatus {
+
+}
+
+@Component({
+ components: {
+ 'status-card': StatusCard
+ },
+})
+export default class Overview extends Vue {
+ private config: Option<Config> = none
+ private moduleRegistry: Option<ModuleRegistryStatus> = none
+ private metricsRegistry: Option<MetricRegistryStatus> = none
+
+
+ get reporterStatus(): StatusInfo {
+ const status: StatusInfo = {
+ heading: 'Reporters',
+ message: 'Unknown',
+ status: Status.Unknown
+ }
+
+ const isReporter = function(module: Module): boolean {
+ return [ModuleKind.Combined, ModuleKind.Span, ModuleKind.Metric].indexOf(module.kind) > 0
+ }
+
+ this.moduleRegistry.forEach(moduleRegistry => {
+ const reportingModules = moduleRegistry.modules.filter(isReporter)
+ if(reportingModules.length > 0) {
+ status.status = Status.Healthy
+ status.message = reportingModules.length + " Active"
+ }
+ })
+
+ return status
+ }
+
+ get metricsStatus(): StatusInfo {
+ const status: StatusInfo = {
+ heading: 'Metrics',
+ message: 'Unknown',
+ status: Status.Unknown
+ }
+
+ this.metricsRegistry.forEach(metricRegistry => {
+ status.message = metricRegistry.metrics.length + " Metrics"
+ })
+
+ return status
+ }
+
+ get instrumentationStatus(): StatusInfo {
+ return {
+ heading: 'Instrumentation',
+ message: 'Unknown',
+ status: Status.Unknown
+ }
+ }
+
+
+ public mounted() {
+ this.refreshData()
+ }
+
+ private refreshData(): void {
+ StatusApi.configStatus().then(config => { this.config = some(config) })
+ StatusApi.metricRegistryStatus().then(metricsRegistry => { this.metricsRegistry = some(metricsRegistry) })
+ StatusApi.moduleRegistryStatus().then(moduleRegistry => {this.moduleRegistry = some(moduleRegistry) })
+ }
+}
+</script>