From c9b145482dfa4576f43a60d0c0e18a7f3046c382 Mon Sep 17 00:00:00 2001 From: Harald Wolff Date: Fri, 5 Apr 2019 00:59:04 +0200 Subject: [PATCH] WIP --- SkyEntities.cs | 6 +++ checks/CheckJob.cs | 13 ++++++- checks/Hostalive.cs | 2 +- checks/SkyCheck.cs | 2 +- checks/SkyCheckState.cs | 37 ++++++++++++++++++ checks/SkyChecker.cs | 19 +++++++++- checks/Ubiquity.cs | 34 +++++++++++++++-- entities/GlobalNetwork.cs | 12 +++++- http/CheckerApi.cs | 7 +++- http/SkyScannerHttpApplication.cs | 5 ++- ln.skyscanner.csproj | 4 ++ templates/static/checks/index.html | 49 ++++++++++++++---------- templates/static/checks/status.html | 59 +++++++++++++++++++++++++++++ templates/static/nav.html | 3 ++ templates/static/network/index.html | 2 +- 15 files changed, 224 insertions(+), 30 deletions(-) create mode 100644 checks/SkyCheckState.cs create mode 100644 templates/static/checks/status.html diff --git a/SkyEntities.cs b/SkyEntities.cs index dd72840..b954a77 100644 --- a/SkyEntities.cs +++ b/SkyEntities.cs @@ -12,11 +12,17 @@ using ln.types.odb; using ln.skyscanner.entities; using System.IO; using LiteDB; +using ln.http.resources; +using System.Linq; namespace ln.skyscanner { public class SkyEntities { + [Callable] + public Node[] Nodes => nodeCollection.ToArray(); + + public SkyScanner SkyScanner { get; } public string BasePath => Path.Combine(SkyScanner.BasePath, "entities"); diff --git a/checks/CheckJob.cs b/checks/CheckJob.cs index a19d013..a0c62e3 100644 --- a/checks/CheckJob.cs +++ b/checks/CheckJob.cs @@ -12,6 +12,8 @@ using ln.types.threads; using ln.skyscanner.entities; using ln.logging; using Newtonsoft.Json; +using ln.types.odb; +using System.Linq; namespace ln.skyscanner.checks { public class CheckJob : PoolJob @@ -36,9 +38,18 @@ namespace ln.skyscanner.checks if (checks[n].IsValid(Node)) { + Query stateQuery = Query.AND( + Query.Equals("CheckName",checks[n].Name), + Query.Equals("UniqueNodeIdentifier", Node.UniqueIdentity) + ); + SkyCheckState checkState = SkyScanner.Instance.Checker.CheckStates.Select(stateQuery).FirstOrDefault(); + try { - checks[n].Check(SkyScanner.Instance.Checker, Node); + checks[n].Check(SkyScanner.Instance.Checker, ref checkState, Node); + if (checkState != null) + SkyScanner.Instance.Checker.CheckStates.Upsert(checkState); + } catch (Exception e) { Logging.Log(e); diff --git a/checks/Hostalive.cs b/checks/Hostalive.cs index 360aac7..25ac580 100644 --- a/checks/Hostalive.cs +++ b/checks/Hostalive.cs @@ -29,7 +29,7 @@ namespace ln.skyscanner.checks public override bool IsCritical => true; public override bool IsValid(Node node) => node.PrimaryIP != null; - public override void Check(SkyChecker skyChecker, Node node) + public override void Check(SkyChecker skyChecker,ref SkyCheckState checkState,Node node) { long roundTripTime = 0; int success = 0; diff --git a/checks/SkyCheck.cs b/checks/SkyCheck.cs index fcae637..ee42d79 100644 --- a/checks/SkyCheck.cs +++ b/checks/SkyCheck.cs @@ -32,7 +32,7 @@ namespace ln.skyscanner.checks public virtual bool IsCritical => false; public abstract bool IsValid(Node node); - public abstract void Check(SkyChecker skyChecker,Node node); + public abstract void Check(SkyChecker skyChecker,ref SkyCheckState checkState,Node node); static SkyCheck() diff --git a/checks/SkyCheckState.cs b/checks/SkyCheckState.cs new file mode 100644 index 0000000..2728595 --- /dev/null +++ b/checks/SkyCheckState.cs @@ -0,0 +1,37 @@ +// /** +// * File: SkyCheckState.cs +// * Author: haraldwolff +// * +// * This file and it's content is copyrighted by the Author and / or copyright holder. +// * Any use wihtout proper permission is illegal and may lead to legal actions. +// * +// * +// **/ +using System; +using ln.skyscanner.entities; +namespace ln.skyscanner.checks +{ + public enum CheckState { OK, WARN, CRITICAL, FAIL, ERROR } + + public class SkyCheckState + { + public readonly String CheckName; + public readonly String UniqueNodeIdentifier; + + public DateTime LastCheckTime { get; set; } + + public double WarnLower { get; set; } = Double.MinValue; + public double WarnUpper { get; set; } = Double.MaxValue; + public double CritLower { get; set; } = Double.MinValue; + public double CritUpper { get; set; } = Double.MaxValue; + + protected SkyCheckState() + { + } + public SkyCheckState(SkyCheck skyCheck,Node node) + { + CheckName = skyCheck.Name; + UniqueNodeIdentifier = node.UniqueIdentity; + } + } +} diff --git a/checks/SkyChecker.cs b/checks/SkyChecker.cs index 807bdec..1eeff1c 100644 --- a/checks/SkyChecker.cs +++ b/checks/SkyChecker.cs @@ -17,15 +17,20 @@ using System.Threading; using System.Linq; using ln.logging; using ln.snmp; +using ln.http.resources; +using ln.types.odb; namespace ln.skyscanner.checks { public class SkyChecker { public string BasePath { get; } + [Callable] public PoolJob[] CurrentJobs => checkPool.CurrentPoolJobs; + [Callable] public PoolJob[] QueuedJobs => checkPool.QueuedJobs; + [Callable] public string[] PerfNames => perfFiles.Keys.ToArray(); public bool ContainsPerfFile(String perfName) => perfFiles.ContainsKey(perfName); @@ -38,10 +43,20 @@ namespace ln.skyscanner.checks bool stopping; + ODB odb; + public ODBCollection CheckStates { get; private set; } + public SkyChecker() { BasePath = Path.Combine(SkyScanner.Instance.BasePath, "perfdb"); + SNMPEngine = new SNMPEngine(); + SNMPEngine.Timeout = 4000; + + odb = new ODB(Path.Combine(BasePath)); + CheckStates = odb.GetCollection(); + CheckStates.EnsureIndex("CheckName"); + CheckStates.EnsureIndex("UniqueNodeIdentifier"); } public void Start() @@ -49,7 +64,7 @@ namespace ln.skyscanner.checks if ((threadScheduler != null) && (threadScheduler.IsAlive)) throw new NotSupportedException("SkyChecker.scheduler() already running"); - checkPool.SetPoolSize(64); + checkPool.SetPoolSize(128); threadScheduler = new Thread(scheduler); threadScheduler.Start(); @@ -155,6 +170,8 @@ namespace ln.skyscanner.checks } } catch (ThreadInterruptedException) { + } catch (OperationCanceledException) + { } } diff --git a/checks/Ubiquity.cs b/checks/Ubiquity.cs index 7d3255b..d68c8cb 100644 --- a/checks/Ubiquity.cs +++ b/checks/Ubiquity.cs @@ -16,8 +16,14 @@ namespace ln.skyscanner.checks } - public override void Check(SkyChecker skyChecker, Node node) + public override void Check(SkyChecker skyChecker,ref SkyCheckState checkState,Node node) { + if ((checkState == null) || !(checkState is UbiquityCheckState)) + { + checkState = new UbiquityCheckState(this, node); + } + UbiquityCheckState ubiquityCheckState = checkState as UbiquityCheckState; + foreach (URI snmpUri in node.FindURIs("snmp")) { using (SnmpInterface snmp = SnmpInterface.FromURI(snmpUri,skyChecker.SNMPEngine)) @@ -38,8 +44,14 @@ namespace ln.skyscanner.checks skyChecker.WritePerfValue(this, "ptp_rx_pwr", node, (double)((Integer)(row[2].Items[1])).LongValue); skyChecker.WritePerfValue(this, "ptp_tx_pwr", node, (double)((Integer)(row[3].Items[1])).LongValue); - skyChecker.WritePerfValue(this, "ptp_rx_rate", node, (double)((Integer)(row[4].Items[1])).LongValue); // ToDo: multiply 8 / delta T - skyChecker.WritePerfValue(this, "ptp_tx_rate", node, (double)((Integer)(row[5].Items[1])).LongValue); // ToDo: multiply 8 / delta T + long rxBytes = ((Integer)(row[4].Items[1])).LongValue; + long txBytes = ((Integer)(row[5].Items[1])).LongValue; + + ubiquityCheckState.RXRate.Update(rxBytes * 8); + ubiquityCheckState.TXRate.Update(txBytes * 8); + + skyChecker.WritePerfValue(this, "ptp_rx_rate", node, ubiquityCheckState.RXRate.Current); + skyChecker.WritePerfValue(this, "ptp_tx_rate", node, ubiquityCheckState.TXRate.Current); } } @@ -51,4 +63,20 @@ namespace ln.skyscanner.checks return (node.Vendor != null) && node.Vendor.Equals("Ubiquity"); } } + + class UbiquityCheckState : SkyCheckState + { + public dVdT RXRate { get; private set; } + public dVdT TXRate { get; private set; } + + public UbiquityCheckState(SkyCheck skyCheck,Node node) + :base(skyCheck,node) + { + RXRate = new dVdT(); + TXRate = new dVdT(); + } + private UbiquityCheckState() + { } + + } } diff --git a/entities/GlobalNetwork.cs b/entities/GlobalNetwork.cs index ace566e..f1d4b9a 100644 --- a/entities/GlobalNetwork.cs +++ b/entities/GlobalNetwork.cs @@ -84,7 +84,8 @@ namespace ln.skyscanner.entities networks.Add(network); } Subnet subnet = FindSubnetForIP(node.PrimaryIP); - networks.Add(subnet.Network); + if (subnet != null) + networks.Add(subnet.Network); foreach (Network4 network in networks) foreach (Node neighbor in FindHostsInSubnet(network)) @@ -275,7 +276,16 @@ namespace ln.skyscanner.entities if (httpIndex.Contains("RouterOS router configuration page")) { node.Vendor = "MicroTik"; + } else if (httpIndex.Contains("mimosa-white-web-logo.png")) + { + node.Vendor = "Mimosa"; + if (httpIndex.Contains("B5c")) + { + node.Product = "B5c"; + } } + + if (crawledHost.GetHint("http.server", "").Equals("Viprinet")) node.Vendor = "Viprinet"; diff --git a/http/CheckerApi.cs b/http/CheckerApi.cs index 8702087..117494e 100644 --- a/http/CheckerApi.cs +++ b/http/CheckerApi.cs @@ -81,10 +81,15 @@ namespace ln.skyscanner.http PerfFile perfFile = SkyScanner.Instance.Checker.GetPerfFile(Name); PerfValue[] perfValues = null; + int interval = 3600; + + if (httpRequest.Query.ContainsKey("interval")) + interval = int.Parse(httpRequest.Query["interval"]); + lock (perfFile) { perfFile.EnsureOpen(); - perfValues = perfFile.QueryTime((int)(TimeSpan.FromHours(1).TotalSeconds), 0); + perfValues = perfFile.QueryTime(interval, 0); perfFile.Close(); } diff --git a/http/SkyScannerHttpApplication.cs b/http/SkyScannerHttpApplication.cs index b598587..2be3a31 100644 --- a/http/SkyScannerHttpApplication.cs +++ b/http/SkyScannerHttpApplication.cs @@ -11,7 +11,8 @@ namespace ln.skyscanner.http public String BasePath { get; private set; } public String TemplatesBasePath => Path.Combine(BasePath, "templates","static"); - + ReflectiveResource refChecker; + ReflectiveResource refEntities; public SkyScannerHttpApplication(SkyScanner skyScanner) { @@ -26,6 +27,8 @@ namespace ln.skyscanner.http RootResource.DefaultResource = staticTemplates; + refEntities = new ReflectiveResource(RootResource, "entities", SkyScanner.Entities); + refChecker = new ReflectiveResource(RootResource, "checker", SkyScanner.Checker); SkyScannerHttpApi api = new SkyScannerHttpApi(this); } diff --git a/ln.skyscanner.csproj b/ln.skyscanner.csproj index 6431c72..7b6cb00 100644 --- a/ln.skyscanner.csproj +++ b/ln.skyscanner.csproj @@ -83,6 +83,7 @@ + @@ -162,6 +163,9 @@ PreserveNewest + + PreserveNewest + diff --git a/templates/static/checks/index.html b/templates/static/checks/index.html index 1a83bbe..7b6823a 100644 --- a/templates/static/checks/index.html +++ b/templates/static/checks/index.html @@ -4,6 +4,14 @@
+
+
@@ -49,32 +57,35 @@ } } ); - function drawChart(perfValues) - { - } - var perfList = skyapi().getJson("api/checker/checks", function(checks){ $.each( checks, function(){ $("#perfList").append( $( "" ) ); }); }); - $("#perfList").change( function(e){ - var perfName = $(this).children("option:selected").val(); - skyapi().getJson("api/checker/checks/" + perfName, function(perfValues){ - chart.data.labels.length = 0; - chart.data.datasets[0].data.length = 0; - chart.data.datasets[0].label = perfName; - $.each( perfValues, function(){ - if (this.TimeStamp != 0) - { - //chart.data.labels.push(this.TimeStamp); - chart.data.datasets[0].data.push( { x: this.TimeStamp, y: this.Value } ); - }; + function showGraph() + { + var perfName = $("#perfList").children("option:selected").val(); + if (perfName) + { + skyapi().getJson("api/checker/checks/" + perfName + "?interval=" + $("#interval").children("option:selected").val(), function(perfValues){ + chart.data.labels.length = 0; + chart.data.datasets[0].data.length = 0; + chart.data.datasets[0].label = perfName; + $.each( perfValues, function(){ + if (this.TimeStamp != 0) + { + chart.data.datasets[0].data.push( { x: this.TimeStamp, y: this.Value } ); + }; + }); + + chart.update(); }); + } + } - chart.update(); - }); - }); + $("#perfList").change( function(e){ showGraph(); } ); + $("#interval").change( function(e){ showGraph(); } ); + skyapi().addRefresh( showGraph, 60 ); diff --git a/templates/static/checks/status.html b/templates/static/checks/status.html new file mode 100644 index 0000000..9a3fe00 --- /dev/null +++ b/templates/static/checks/status.html @@ -0,0 +1,59 @@ +<%frame "frame.html"%> + +

Checker Status

+
+ +
+
+

Current Jobs

+
+
+
+
+
+

Queued Jobs

+
+
+
+ + diff --git a/templates/static/nav.html b/templates/static/nav.html index 799cc5f..805217d 100644 --- a/templates/static/nav.html +++ b/templates/static/nav.html @@ -28,6 +28,9 @@

Überwachung

+
+
Status
+
diff --git a/templates/static/network/index.html b/templates/static/network/index.html index 1056725..8a05bb9 100644 --- a/templates/static/network/index.html +++ b/templates/static/network/index.html @@ -115,7 +115,7 @@ function refreshNodeTable() { - skyapi().call("api/network","GetNodes",[], + skyapi().getJson("entities/Nodes", function(rows){ $("#nodeTable").DataTable().clear().rows.add( rows ).draw(); });