broken
Harald Wolff 2019-04-05 00:59:04 +02:00
parent 9905238db5
commit c9b145482d
15 changed files with 224 additions and 30 deletions

View File

@ -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");

View File

@ -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<SkyCheckState>("CheckName",checks[n].Name),
Query.Equals<SkyCheckState>("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);

View File

@ -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;

View File

@ -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()

View File

@ -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;
}
}
}

View File

@ -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<SkyCheckState> 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<SkyCheckState>();
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)
{
}
}

View File

@ -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()
{ }
}
}

View File

@ -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("<title>RouterOS router configuration page</title>"))
{
node.Vendor = "MicroTik";
} else if (httpIndex.Contains("mimosa-white-web-logo.png"))
{
node.Vendor = "Mimosa";
if (httpIndex.Contains("<title>B5c</title>"))
{
node.Product = "B5c";
}
}
if (crawledHost.GetHint("http.server", "").Equals("Viprinet"))
node.Vendor = "Viprinet";

View File

@ -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();
}

View File

@ -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);
}

View File

@ -83,6 +83,7 @@
<Compile Include="checks\CheckJob.cs" />
<Compile Include="http\CheckerApi.cs" />
<Compile Include="checks\Ubiquity.cs" />
<Compile Include="checks\SkyCheckState.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
@ -162,6 +163,9 @@
<None Include="templates\static\checks\index.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\checks\status.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Folder Include="identify\" />

View File

@ -4,6 +4,14 @@
<div class="flex row">
<div>
<select id="interval" style="width: 180px;">
<option value="3600">1 Stunde</option>
<option value="21600">6 Stunden</option>
<option value="43200">12 Stunden</option>
<option value="86400">1 Tag</option>
<option value="604800">1 Woche</option>
</select><br/>
<br/>
<select size="25" id="perfList"></select>
</div>
<div>
@ -49,32 +57,35 @@
}
} );
function drawChart(perfValues)
{
}
var perfList = skyapi().getJson("api/checker/checks", function(checks){
$.each( checks, function(){
$("#perfList").append( $( "<option value='"+ this +"'>" + this + "</option>" ) );
});
});
$("#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 );
</script>

View File

@ -0,0 +1,59 @@
<%frame "frame.html"%>
<h1>Checker Status</h1>
<br/>
<div class="flex column">
<div>
<h2>Current Jobs</h2>
<div style="width: 100%;">
<table id="CurrentPoolJobs"></table>
</div>
</div>
<div>
<h2>Queued Jobs</h2>
<table id="QueuedPoolJobs"></table>
</div>
</div>
<script type="text/javascript">
var pbar = $().dataTable.render.percentBar('round','#fff', '#FF9CAB', '#FF0033', '#FF9CAB', 0, 'solid');
var dtDef = {
columns: [
{ title: "Name", data: "Name" },
{ title: "Progress", data: "Progress" },
{ title: "State", data: "State" },
{ title: "JobState", data: "JobState" }
],
columnDefs: [
{
targets: 1,
render: function(d, t, row){ d *= 100.0; return pbar(d,t,row); }
}
]
};
$("#CurrentPoolJobs").DataTable( dtDef );
$("#QueuedPoolJobs").DataTable( dtDef );
function refresh()
{
skyapi().getJson("checker/CurrentJobs", function(data){
if (!data)
data = []
$("#CurrentPoolJobs").DataTable().clear();
$("#CurrentPoolJobs").DataTable().rows.add( data ).draw();
});
skyapi().getJson("checker/QueuedJobs", function(data){
if (!data)
data = []
$("#QueuedPoolJobs").DataTable().clear();
$("#QueuedPoolJobs").DataTable().rows.add( data ).draw();
});
}
skyapi().addRefresh( refresh, 1 );
</script>

View File

@ -28,6 +28,9 @@
</div>
<div>
<h1>&Uuml;berwachung</h1>
<div>
<a href="/static/checks/status.html" onclick="skyapi().loadPage('static/checks/status.html'); return false;"><div>Status</div></a>
</div>
<div>
<a href="/static/checks/index.html" onclick="skyapi().loadPage('static/checks/index.html'); return false;"><div>Checks</div></a>
</div>

View File

@ -115,7 +115,7 @@
function refreshNodeTable()
{
skyapi().call("api/network","GetNodes",[],
skyapi().getJson("entities/Nodes",
function(rows){
$("#nodeTable").DataTable().clear().rows.add( rows ).draw();
});