Ver Fonte

:art: Display metrics to summary

mudler há 3 anos atrás
pai
commit
7056695041
3 ficheiros alterados com 321 adições e 4 exclusões
  1. 178 2
      api/public/index.html
  2. 138 2
      api/public/index.tmpl
  3. 5 0
      api/public/js/apexcharts.min.js

+ 178 - 2
api/public/index.html

@@ -18,6 +18,7 @@
     <title>EdgeVPN</title>
     <meta name="description" content="Edgevpn dashboard">
     <meta name="keywords" content="edgevpn,dashboard">
+    <script src="/js/apexcharts.min.js"></script>
     <script src="/js/alpine-magic-helpers.min.js" defer></script>
     <script src="/js/alpine.min.js" defer></script>   
     <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css" integrity="sha512-KfkfwYDsLkIlwQp6LFnl8zNdLGxu9YAA1QvwINks4PhcElQSvqcyVLLD9aMhXd13uQjoXtEKNosOWaZqXgel0g==" crossorigin="anonymous" referrerpolicy="no-referrer" />
@@ -1630,7 +1631,7 @@
 		
 		<div class="w-full px-4 md:px-0 md:mt-8 mb-16 text-gray-800 leading-normal"
             x-data="summary()"
-            x-init="$interval(updateItems, 1500)"
+            x-init="$interval(updateItems, 1500); initChart()"
         >
 			<!--Summary Content-->
 			
@@ -1772,7 +1773,81 @@
                     <!--/Metric Card-->
                 </div>
 
-      </div>
+
+                
+                
+
+
+
+
+                <div class="w-full md:w-1/2 xl:w-1/3 p-3">
+                    <!--Metric Card-->
+                    <div class="dark:bg-gray-900 bg-white-100 dark:border-gray-800 dark:border-gray-600 border-b-4 rounded shadow p-2">
+                        <div class="flex flex-row items-center">
+                            <div class="flex-shrink pr-4">
+                                <div class="rounded p-3 bg-cyan-600"><i class="fas fa-download fa-2x fa-fw fa-inverse"></i></div>
+                            </div>
+                            <div class="flex-1 text-right md:text-center">
+                                <h5 class="font-bold uppercase text-gray-400">Total downloaded</h5>
+                                <h3 class="font-bold text-3xl text-gray-600" x-text="bytesToSize(metrics.TotalIn)"></h3>
+                            </div>
+                        </div>
+                    </div>
+                    <!--/Metric Card-->
+                </div>
+  
+
+                <div class="w-full md:w-1/2 xl:w-1/3 p-3 text-gray-800 ">
+                  <div class="dark:bg-gray-900 rounded shadow dark:border-gray-600 border-b-4 ">
+                        <div class="bg-white-200 dark:bg-gray-900 p-3">
+                            <h5 class="font-bold float-left uppercase text-gray-400">
+                            <span class="rounded p-1 bg-teal-600"><i class="fa-duotone fa-right-left fa-fw fa-inverse"></i></span> 
+                              Bandwidth
+                            </h5>
+                            <h5 class="font-bold uppercase float-right text-gray-600">
+                            <span class="rounded p-1 bg-cyan-600"><i class="fas fa-arrow-down fa-fw fa-inverse"></i></span> 
+                            <span x-text="bytesToSize(metrics.RateIn)"></span>
+                            <span class="rounded p-1 bg-amber-600"><i class="fas fa-arrow-up fa-fw fa-inverse"></i></span> 
+                            <span x-text="bytesToSize(metrics.RateOut)"></span>
+                            </h5>
+                        </div>
+                        <br>
+                        <div class=" relative mt-1  ">
+                            <!-- Network stat Card-->
+                            <div class="dark:bg-gray-900 bg-white-100 rounded shadow p-2">
+                                <div class="flex flex-row items-center">
+                                    <div class="flex-1 text-right md:text-center">
+                                        <div x-ref="chart"></div>
+                                    </div>
+                                </div>
+                            </div>
+                            <!--/Network stat Card-->
+                        </div>
+                  </div>
+                </div>
+
+                
+                
+
+
+
+
+                <div class="w-full md:w-1/2 xl:w-1/3 p-3">
+                    <!--Metric Card-->
+                    <div class="dark:bg-gray-900 bg-white-100 dark:border-gray-800 dark:border-gray-600 border-b-4 rounded shadow p-2">
+                        <div class="flex flex-row items-center">
+                            <div class="flex-shrink pr-4">
+                                <div class="rounded p-3 bg-amber-600"><i class="fas fa-upload fa-2x fa-fw fa-inverse"></i></div>
+                            </div>
+                            <div class="flex-1 text-right md:text-center">
+                                <h5 class="font-bold uppercase text-gray-400">Total uploaded</h5>
+                                <h3 class="font-bold text-3xl text-gray-600" x-text="bytesToSize(metrics.TotalOut)"></h3>
+                            </div>
+                        </div>
+                    </div>
+                    <!--/Metric Card-->
+                </div>
+  
 
 			<!--Divider-->
 			<hr class="border-b-2 border-gray-600 my-8 mx-4">
@@ -2030,6 +2105,34 @@
 	</footer>
 
 <script>
+    function bytesToSize(bytes, decimals = 2) {
+      if (bytes === 0) return '0 Bytes';
+
+      const k = 1024;
+      const dm = decimals < 0 ? 0 : decimals;
+      const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
+
+      const i = Math.floor(Math.log(bytes) / Math.log(k));
+
+      var s = sizes[i]
+      if (!sizes[i]) {
+          s = "B"
+      }
+      return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + s;
+    }
+
+    function scaleSize(bytes, scale = 1, decimals = 2) {
+      if (bytes === 0) return '0';
+
+      const k = 1024;
+      const dm = decimals < 0 ? 0 : decimals;
+
+      //const i = Math.floor(Math.log(bytes) / Math.log(k));
+      //console.log(i)
+
+      return parseFloat((bytes / Math.pow(k, scale)).toFixed(dm));
+    }
+        
     const range = (start, stop, step) => Array.from({ length: (stop - start) / step + 1}, (_, i) => start + (i * step));
     function calcPages(n, total, size) {
               start = 1;
@@ -2704,10 +2807,83 @@
     function summary(){
         return {
             summary: {},
+            chart: null,
+            metrics: {},
+            initChart() {
+            this.chart = new ApexCharts(this.$refs.chart, {
+                  chart: {
+                    type: 'area',
+                    height: 80,
+                    sparkline: {
+                      enabled: true
+                    },
+                    dropShadow: {
+                      enabled: true,
+                      top: 1,
+                      left: 1,
+                      blur: 2,
+                      opacity: 0.2,
+                    }
+                  },
+                  dataLabels: {
+                    enabled: false,
+                  },
+                  series: [
+                    {
+                      name: "Download",
+                      data: [],
+                    },
+                    {
+                      name: "Upload",
+                      data: [],
+                    },
+                  ],
+                  stroke: {
+                    curve: 'smooth'
+                  },
+                  markers: {
+                    size: 0
+                  },
+                  grid: {
+                    padding: {
+                      top: 20,
+                      bottom: 10,
+                    }
+                  },
+                  colors: ['#247BA0', '#FF1654' ],
+               
+                  noData: {
+                    text: "Loading...",
+                  },
+                  xaxis: {
+                    labels: {
+                      show: false,
+                    },
+                  },
+                  tooltip: {
+                    x: {
+                      show: false
+                    },
+                    y: {
+                        formatter: function(value, { series, seriesIndex, dataPointIndex, w }) {
+                          return value + ' KB/s'
+                        }
+                    }
+                  }
+          })
+          this.chart.render()
+            },
             updateItems() {
               fetch('/api/summary')
                 .then(response => response.json())
                 .then(data => this.summary = data )
+              fetch('/api/metrics')
+                .then(response => response.json())
+                .then(data => {
+                      this.metrics = data;
+                      this.chart.appendData([{ data: [ scaleSize(data.RateIn) ] }, { data: [ scaleSize(data.RateOut) ] } ]);
+
+                 } )             
             }
         };
     }

+ 138 - 2
api/public/index.tmpl

@@ -7,6 +7,7 @@
     <title>EdgeVPN</title>
     <meta name="description" content="Edgevpn dashboard">
     <meta name="keywords" content="edgevpn,dashboard">
+    <script src="/js/apexcharts.min.js"></script>
     <script src="/js/alpine-magic-helpers.min.js" defer></script>
     <script src="/js/alpine.min.js" defer></script>   
     <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css" integrity="sha512-KfkfwYDsLkIlwQp6LFnl8zNdLGxu9YAA1QvwINks4PhcElQSvqcyVLLD9aMhXd13uQjoXtEKNosOWaZqXgel0g==" crossorigin="anonymous" referrerpolicy="no-referrer" />
@@ -201,7 +202,7 @@
 		
 		<div class="w-full px-4 md:px-0 md:mt-8 mb-16 text-gray-800 leading-normal"
             x-data="summary()"
-            x-init="$interval(updateItems, 1500)"
+            x-init="$interval(updateItems, 1500); initChart()"
         >
 			<!--Summary Content-->
 			
@@ -223,7 +224,41 @@
 
                 {{ $opts:= dict "name" "Services" "color" "bg-sky-600" "icon" "fa-solid fa-car-tunnel" "field" "summary.Services"}}
                 {{ template "metric_card" $opts}}
-      </div>
+
+                {{ $opts:= dict "name" "Total downloaded" "color" "bg-cyan-600" "icon" "fas fa-download" "field" "bytesToSize(metrics.TotalIn)"}}
+                {{ template "metric_card" $opts}}  
+
+                <div class="w-full md:w-1/2 xl:w-1/3 p-3 text-gray-800 ">
+                  <div class="dark:bg-gray-900 rounded shadow dark:border-gray-600 border-b-4 ">
+                        <div class="bg-white-200 dark:bg-gray-900 p-3">
+                            <h5 class="font-bold float-left uppercase text-gray-400">
+                            <span class="rounded p-1 bg-teal-600"><i class="fa-duotone fa-right-left fa-fw fa-inverse"></i></span> 
+                              Bandwidth
+                            </h5>
+                            <h5 class="font-bold uppercase float-right text-gray-600">
+                            <span class="rounded p-1 bg-cyan-600"><i class="fas fa-arrow-down fa-fw fa-inverse"></i></span> 
+                            <span x-text="bytesToSize(metrics.RateIn)"></span>
+                            <span class="rounded p-1 bg-amber-600"><i class="fas fa-arrow-up fa-fw fa-inverse"></i></span> 
+                            <span x-text="bytesToSize(metrics.RateOut)"></span>
+                            </h5>
+                        </div>
+                        <br>
+                        <div class=" relative mt-1  ">
+                            <!-- Network stat Card-->
+                            <div class="dark:bg-gray-900 bg-white-100 rounded shadow p-2">
+                                <div class="flex flex-row items-center">
+                                    <div class="flex-1 text-right md:text-center">
+                                        <div x-ref="chart"></div>
+                                    </div>
+                                </div>
+                            </div>
+                            <!--/Network stat Card-->
+                        </div>
+                  </div>
+                </div>
+
+                {{ $opts:= dict "name" "Total uploaded" "color" "bg-amber-600" "icon" "fas fa-upload" "field" "bytesToSize(metrics.TotalOut)"}}
+                {{ template "metric_card" $opts}}  
 
 			<!--Divider-->
 			<hr class="border-b-2 border-gray-600 my-8 mx-4">
@@ -274,6 +309,34 @@
 	</footer>
 
 <script>
+    function bytesToSize(bytes, decimals = 2) {
+      if (bytes === 0) return '0 Bytes';
+
+      const k = 1024;
+      const dm = decimals < 0 ? 0 : decimals;
+      const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
+
+      const i = Math.floor(Math.log(bytes) / Math.log(k));
+
+      var s = sizes[i]
+      if (!sizes[i]) {
+          s = "B"
+      }
+      return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + s;
+    }
+
+    function scaleSize(bytes, scale = 1, decimals = 2) {
+      if (bytes === 0) return '0';
+
+      const k = 1024;
+      const dm = decimals < 0 ? 0 : decimals;
+
+      //const i = Math.floor(Math.log(bytes) / Math.log(k));
+      //console.log(i)
+
+      return parseFloat((bytes / Math.pow(k, scale)).toFixed(dm));
+    }
+        
     const range = (start, stop, step) => Array.from({ length: (stop - start) / step + 1}, (_, i) => start + (i * step));
     function calcPages(n, total, size) {
               start = 1;
@@ -395,10 +458,83 @@
     function summary(){
         return {
             summary: {},
+            chart: null,
+            metrics: {},
+            initChart() {
+            this.chart = new ApexCharts(this.$refs.chart, {
+                  chart: {
+                    type: 'area',
+                    height: 80,
+                    sparkline: {
+                      enabled: true
+                    },
+                    dropShadow: {
+                      enabled: true,
+                      top: 1,
+                      left: 1,
+                      blur: 2,
+                      opacity: 0.2,
+                    }
+                  },
+                  dataLabels: {
+                    enabled: false,
+                  },
+                  series: [
+                    {
+                      name: "Download",
+                      data: [],
+                    },
+                    {
+                      name: "Upload",
+                      data: [],
+                    },
+                  ],
+                  stroke: {
+                    curve: 'smooth'
+                  },
+                  markers: {
+                    size: 0
+                  },
+                  grid: {
+                    padding: {
+                      top: 20,
+                      bottom: 10,
+                    }
+                  },
+                  colors: ['#247BA0', '#FF1654' ],
+               
+                  noData: {
+                    text: "Loading...",
+                  },
+                  xaxis: {
+                    labels: {
+                      show: false,
+                    },
+                  },
+                  tooltip: {
+                    x: {
+                      show: false
+                    },
+                    y: {
+                        formatter: function(value, { series, seriesIndex, dataPointIndex, w }) {
+                          return value + ' KB/s'
+                        }
+                    }
+                  }
+          })
+          this.chart.render()
+            },
             updateItems() {
               fetch('/api/summary')
                 .then(response => response.json())
                 .then(data => this.summary = data )
+              fetch('/api/metrics')
+                .then(response => response.json())
+                .then(data => {
+                      this.metrics = data;
+                      this.chart.appendData([{ data: [ scaleSize(data.RateIn) ] }, { data: [ scaleSize(data.RateOut) ] } ]);
+
+                 } )             
             }
         };
     }

Diff do ficheiro suprimidas por serem muito extensas
+ 5 - 0
api/public/js/apexcharts.min.js


Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff