From 11fc4117be9ef93f3471ed22de596a6bd8088eb9 Mon Sep 17 00:00:00 2001
From: Ivan Topolnjak <ivantopo@gmail.com>
Date: Mon, 4 Feb 2019 19:16:07 +0100
Subject: update the status page to show modules information and metrics

---
 kamon-status/src/views/Overview.vue | 134 +++++++++++++++++++++---------------
 1 file changed, 78 insertions(+), 56 deletions(-)

(limited to 'kamon-status/src/views/Overview.vue')

diff --git a/kamon-status/src/views/Overview.vue b/kamon-status/src/views/Overview.vue
index e0802eb7..2d6e8dd7 100644
--- a/kamon-status/src/views/Overview.vue
+++ b/kamon-status/src/views/Overview.vue
@@ -1,19 +1,48 @@
 <template>
   <div class="container">
     <div class="row">
-      <div class="col-12 pb-3">
-        <h2>Overview</h2>
+      <div class="col-12 pt-4 pb-2">
+        <h3>Status</h3>
       </div>
-      <div class="col-6 col-md-4 p-2">
-        <status-card :statusInfo="instrumentationStatus"></status-card>
+      <div class="col-12">
+        <card>
+          <div class="row py-2 no-gutters">
+            <div class="col-12 col-md-3 py-2 px-3">
+              <div class="text-uppercase text-label pb-2">Instrumentation</div>
+              <h5>Active</h5>
+            </div>
+            <div class="col-12 col-md-3 py-2 px-3">
+              <div class="text-uppercase text-label pb-2">Reporters</div>
+              <h5>{{ activeReporters.length }} Started</h5>
+            </div>
+            <div class="col-12 col-md-3 py-2 px-3">
+              <div class="text-uppercase text-label pb-2">Metrics</div>
+              <h5>{{metricsStatusMessage}}</h5>
+            </div>
+          </div>
+        </card>
       </div>
-      <div class="col-6 col-md-4 p-2">
-        <status-card :statusInfo="reporterStatus"></status-card>
+
+      <div class="col-12 pt-4 pb-2">
+        <h3>Reporters</h3>
+      </div>
+      <div class="col-12 py-1" v-for="reporter in reporterModules" :key="reporter.name">
+        <module-status :moduleStatus="reporter" />
+      </div>
+
+      <div class="col-12 pt-4 pb-2" v-if="plainModules.length > 0">
+        <h2>Modules</h2>
       </div>
-      <div class="col-6 col-md-4 p-2">
-        <status-card :statusInfo="metricsStatus"></status-card>
+      <div class="col-12 py-1" v-for="module in plainModules" :key="module.name">
+        <module-status :moduleStatus="module" />
       </div>
 
+      <div class="col-12 pt-4 pb-2" v-if="metrics.length > 0">
+        <h2>Metrics</h2>
+      </div>
+      <div class="col-12 mb-5">
+        <metric-list :metrics="metrics"/>
+      </div>
     </div>
   </div>
 </template>
@@ -21,66 +50,51 @@
 <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 {
-
-}
+import ModuleStatus from '../components/ModuleStatus.vue'
+import Card from '../components/Card.vue'
+import MetricList from '../components/MetricList.vue'
+import {StatusApi, Settings, ModuleRegistry, ModuleKind, MetricRegistry, Module, Metric} from '../api/StatusApi'
 
 @Component({
   components: {
-    'status-card': StatusCard
+    'card': Card,
+    'module-status': ModuleStatus,
+    'metric-list': MetricList
   },
 })
 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"
-      }
-    })
+  private settings: Option<Settings> = none
+  private moduleRegistry: Option<ModuleRegistry> = none
+  private metricsRegistry: Option<MetricRegistry> = none
+
+  get reporterModules(): Module[] {
+    return this.moduleRegistry
+      .map(moduleRegistry => moduleRegistry.modules.filter(this.isReporter))
+      .getOrElse([])
+  }
 
-    return status
+  get activeReporters(): Module[] {
+    return this.reporterModules.filter(this.isStarted)
   }
 
-  get metricsStatus(): StatusInfo {
-    const status: StatusInfo = {
-      heading: 'Metrics',
-      message: 'Unknown',
-      status: Status.Unknown
-    }
+  get plainModules(): Module[] {
+    return this.moduleRegistry
+      .map(moduleRegistry => moduleRegistry.modules.filter(m => !this.isReporter(m)))
+      .getOrElse([])
+  }
 
-    this.metricsRegistry.forEach(metricRegistry => {
-      status.message = metricRegistry.metrics.length + " Metrics"
-    })
+  get trackedMetrics(): Option<number> {
+    return this.metricsRegistry.map(metricRegistry => metricRegistry.metrics.length)
+  }
 
-    return status
+  get metricsStatusMessage(): string {
+    return this.trackedMetrics.map(mc => mc + ' Tracked').getOrElse('Unknown')
   }
 
-  get instrumentationStatus(): StatusInfo {
-    return {
-      heading: 'Instrumentation',
-      message: 'Unknown',
-      status: Status.Unknown
-    }
+  get metrics(): Metric[] {
+    return this.metricsRegistry
+      .map(mr => mr.metrics)
+      .getOrElse([])
   }
 
 
@@ -89,9 +103,17 @@ export default class Overview extends Vue {
   }
 
   private refreshData(): void {
-    StatusApi.configStatus().then(config => { this.config = some(config) })
+    StatusApi.settings().then(settings => { this.settings = some(settings) })
     StatusApi.metricRegistryStatus().then(metricsRegistry => { this.metricsRegistry = some(metricsRegistry) })
     StatusApi.moduleRegistryStatus().then(moduleRegistry => {this.moduleRegistry = some(moduleRegistry) })
   }
+
+  private isReporter(module: Module): boolean {
+      return [ModuleKind.Combined, ModuleKind.Span, ModuleKind.Metric].indexOf(module.kind) > 0
+    }
+
+  private isStarted(module: Module): boolean {
+    return module.isStarted
+  }
 }
 </script>
-- 
cgit v1.2.3

