Beta 4.4.

broken
Harald Wolff 2019-04-04 00:50:53 +02:00
parent c1174d29a4
commit 488f72a940
21 changed files with 636 additions and 110 deletions

View File

@ -10,6 +10,7 @@ using System.Threading;
using sharp.logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using ln.skyscanner.checks;
namespace ln.skyscanner
{
[JsonConverter(typeof(StringEnumConverter))]
@ -27,6 +28,7 @@ namespace ln.skyscanner
public HTTPServer HTTPServer { get; private set; }
public Crawler Crawler { get; private set; }
public SkyEntities Entities { get; private set; }
public SkyChecker Checker { get; private set; }
public MemoryLogger MemoryLogger { get; private set; }
@ -47,6 +49,7 @@ namespace ln.skyscanner
Arguments = args;
Entities = new SkyEntities(this);
Checker = new SkyChecker();
}
private SkyScanner()
{
@ -63,6 +66,7 @@ namespace ln.skyscanner
StartHttpServer();
StartCrawler();
Checker.Start();
lock (this)
{
@ -74,6 +78,8 @@ namespace ln.skyscanner
{
Logging.Log(LogLevel.INFO, "SkyScanner: Stop()");
Checker.Stop();
StopCrawler();
new Thread(() => ConveniencePool.Close()).Start();

View File

@ -1,72 +0,0 @@
// /**
// * File: Hostalive.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.types;
using ln.skyscanner.entities;
using ln.perfdb;
using System.Net.NetworkInformation;
using ln.logging;
using ln.perfdb.storage;
namespace ln.skyscanner.check
{
public class Hostalive : Check
{
public static String CalcCheckName(Node host)
{
return String.Format("hostalive-{0}", host.PrimaryIP.ToString());
}
public Node Host;
public Hostalive(Node node)
:base(CalcCheckName(node))
{
Host = node;
}
public override void CheckImplementation(IPerfFileProvider perfProvider)
{
Ping ping = new Ping();
long roundTripTime = 0;
int success = 0;
int n;
for (n = 0; n < 4; n++)
{
PingReply reply = ping.Send(Host.PrimaryIP, 250);
if (reply.Status == IPStatus.Success)
{
success++;
roundTripTime += reply.RoundtripTime;
}
}
float fSuccess = (float)success / (float)n;
PerfFile pfSuccess = perfProvider.GetPerfFile(GetPerfName("LOSS"));
pfSuccess.Write(new PerfValue(fSuccess));
if (success > 0)
{
roundTripTime /= success;
Logging.Log(LogLevel.INFO, "HOSTALIVE: IP {0} reachable ({1}/10) {2}ms", Host.PrimaryIP, success, roundTripTime);
PerfFile pfRoundTrip = perfProvider.GetPerfFile(GetPerfName("RTA"));
pfRoundTrip.Write(new PerfValue(roundTripTime));
}
else
{
Logging.Log(LogLevel.INFO, "HOSTALIVE: IP {0} unreachable", Host.PrimaryIP);
}
}
}
}

72
checks/CheckJob.cs 100644
View File

@ -0,0 +1,72 @@
// /**
// * File: CheckTask.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.types.threads;
using ln.skyscanner.entities;
using ln.logging;
using Newtonsoft.Json;
namespace ln.skyscanner.checks
{
public class CheckJob : PoolJob
{
[JsonIgnore]
public Node Node { get; }
public CheckJob(Node node)
{
Name = String.Format("Interval check: {0} [{1}]",node.UniqueIdentity,node.PrimaryIP.ToString());
Node = node;
}
public override void RunJob()
{
SkyCheck[] checks = SkyCheck.SkyChecks;
for (int n=0;n<checks.Length;n++)
{
setState("current check: {0}", checks[n].Name);
Progress = (double)n / (double)checks.Length;
if (checks[n].IsValid(Node))
{
try
{
checks[n].Check(SkyScanner.Instance.Checker, Node);
} catch (Exception e)
{
Logging.Log(e);
if (checks[n].IsCritical)
break;
}
}
else if (checks[n].IsCritical)
{
break;
}
}
}
public override int GetHashCode()
{
return Node.UniqueIdentity.GetHashCode();
}
public override bool Equals(object obj)
{
if (obj is CheckJob)
{
return Node.UniqueIdentity.Equals((obj as CheckJob).Node.UniqueIdentity);
}
return false;
}
}
}

View File

@ -0,0 +1,57 @@
// /**
// * File: Hostalive.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.types;
using ln.skyscanner.entities;
using ln.perfdb;
using System.Net.NetworkInformation;
using ln.logging;
using ln.perfdb.storage;
namespace ln.skyscanner.checks
{
public class Hostalive : SkyCheck
{
Ping Ping { get; }
public Hostalive()
: base("hostalive")
{
Ping = new Ping();
}
public override bool IsValid(Node node) => node.PrimaryIP != null;
public override void Check(SkyChecker skyChecker, Node node)
{
long roundTripTime = 0;
int success = 0;
int n;
for (n = 0; n < 4; n++)
{
PingReply reply = Ping.Send(node.PrimaryIP, 250);
if (reply.Status == IPStatus.Success)
{
success++;
roundTripTime += reply.RoundtripTime;
}
}
float fSuccess = (float)success / (float)n;
skyChecker.WritePerfValue(this,"replies",node,fSuccess);
if (success > 0)
{
roundTripTime /= success;
skyChecker.WritePerfValue(this, "rta", node, roundTripTime);
}
}
}
}

43
checks/SkyCheck.cs 100644
View File

@ -0,0 +1,43 @@
// /**
// * File: SkyCheck.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;
using System.IO;
using System.Collections.Generic;
namespace ln.skyscanner.checks
{
public abstract class SkyCheck
{
/* Static */
static List<SkyCheck> skyChecks = new List<SkyCheck>();
public static SkyCheck[] SkyChecks => skyChecks.ToArray();
public static void AddSkyCheck(SkyCheck skyCheck) => skyChecks.Add(skyCheck);
/* Instance */
public SkyCheck(String checkName)
{
Name = checkName;
}
public string Name { get; }
public virtual bool IsCritical => false;
public abstract bool IsValid(Node node);
public abstract void Check(SkyChecker skyChecker,Node node);
static SkyCheck()
{
AddSkyCheck(new Hostalive());
}
}
}

View File

@ -0,0 +1,167 @@
// /**
// * File: SkyChecker.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 System.IO;
using ln.types.btree;
using ln.perfdb.storage;
using ln.skyscanner.entities;
using ln.types.threads;
using System.Threading;
using System.Linq;
using ln.logging;
namespace ln.skyscanner.checks
{
public class SkyChecker
{
public string BasePath { get; }
public PoolJob[] CurrentJobs => checkPool.CurrentPoolJobs;
public PoolJob[] QueuedJobs => checkPool.QueuedJobs;
public string[] PerfNames => perfFiles.Keys.ToArray();
public bool ContainsPerfFile(String perfName) => perfFiles.ContainsKey(perfName);
BTree<string, PerfFile> perfFiles = new BTree<string, PerfFile>();
Pool checkPool = new Pool(0);
Thread threadScheduler;
bool stopping;
public SkyChecker()
{
BasePath = Path.Combine(SkyScanner.Instance.BasePath, "perfdb");
}
public void Start()
{
if ((threadScheduler != null) && (threadScheduler.IsAlive))
throw new NotSupportedException("SkyChecker.scheduler() already running");
checkPool.SetPoolSize(64);
threadScheduler = new Thread(scheduler);
threadScheduler.Start();
}
public void Stop()
{
stopping = true;
if (threadScheduler!=null && threadScheduler.IsAlive)
{
threadScheduler.Interrupt();
}
checkPool.Abort();
checkPool.Close();
foreach (PerfFile perfFile in perfFiles.Values)
{
if (perfFile.IsOpen)
perfFile.Close();
}
perfFiles.Clear();
}
public void WritePerfValue(SkyCheck skyCheck,String vName,Node node,double value)
{
PerfFile perfFile = GetPerfFile(skyCheck, vName, node);
lock (perfFile)
{
perfFile.EnsureOpen();
perfFile.Write(DateTimeOffset.Now.ToUnixTimeSeconds(), value);
perfFile.Close();
}
}
public PerfFile GetPerfFile(string perfName)
{
return perfFiles[perfName];
}
private PerfFile GetPerfFile(SkyCheck skyCheck, String vName, Node node)
{
String checkPath = String.Format("{0}_{1}", node.UniqueIdentity, skyCheck.Name);
String perfName = String.Format("{0}_{1}",checkPath,vName);
if (node.AddCheck(perfName))
{
SkyScanner.Instance.Entities.nodeCollection.Upsert(node);
}
lock (this)
{
if (!perfFiles.ContainsKey(perfName))
{
String perfDirectory = Path.Combine(BasePath, node.UniqueIdentity, skyCheck.Name);
if (!Directory.Exists(perfDirectory))
Directory.CreateDirectory(perfDirectory);
String perfFileName = Path.Combine(BasePath, node.UniqueIdentity, skyCheck.Name, String.Format("{0}.perf", vName));
PerfFile perfFile = new PerfFile(perfFileName);
perfFile.Open();
if (perfFile.FirstSection == null)
{
PerfFile.PerfFileSection s1 = new PerfFile.PerfFileSection(perfFile, null, TimeSpan.FromDays(28), 60, AggregationMethod.AVERAGE);
PerfFile.PerfFileSection s2 = new PerfFile.PerfFileSection(perfFile, s1, TimeSpan.FromDays(56), 300, AggregationMethod.AVERAGE);
PerfFile.PerfFileSection s3 = new PerfFile.PerfFileSection(perfFile, s2, TimeSpan.FromDays(84), 900, AggregationMethod.AVERAGE);
PerfFile.PerfFileSection s4 = new PerfFile.PerfFileSection(perfFile, s3, TimeSpan.FromDays(168), 1800, AggregationMethod.AVERAGE);
PerfFile.PerfFileSection s5 = new PerfFile.PerfFileSection(perfFile, s4, TimeSpan.FromDays(750), 3600, AggregationMethod.AVERAGE);
}
perfFile.Close();
perfFiles.Add(perfName, perfFile);
}
return perfFiles[perfName];
}
}
private void scheduler()
{
long nextMinute = DateTimeOffset.Now.ToUnixTimeMilliseconds();
try
{
while (!stopping)
{
int n = 0;
foreach (Node node in SkyScanner.Instance.Entities.GlobalNetwork.Nodes)
{
CheckJob checkJob = new CheckJob(node);
if (checkPool.Enqueue(checkJob))
n++;
}
Logging.Log(LogLevel.INFO, "SkyChecker.scheduler(): scheduled {0} checks", n);
while ((nextMinute - DateTimeOffset.Now.ToUnixTimeMilliseconds()) < 0)
nextMinute += 60000;
Thread.Sleep((int)(nextMinute - DateTimeOffset.Now.ToUnixTimeMilliseconds()));
}
} catch (ThreadInterruptedException)
{
}
}
public ComponentState State
{
get
{
return ComponentState.INITIALIZED;
}
}
}
}

View File

@ -22,6 +22,7 @@ using Newtonsoft.Json;
using ln.skyscanner.crawl.tests;
using System.Runtime.Remoting.Messaging;
using ln.skyscanner.crawl.service;
using ln.types.net;
namespace ln.skyscanner.crawl
{
public class Crawl : PoolJob
@ -114,6 +115,9 @@ namespace ln.skyscanner.crawl
bool updated = Crawler.CrawledHosts.Upsert( Host );
foreach (Network4 network in Host.Networks)
Crawler.EnsureSubnet(network);
setState("Updating global network");
SkyScanner.Instance.Entities.GlobalNetwork.EnqueueUpdate(Host);
}

View File

@ -13,24 +13,13 @@ using System.Net;
using System.Collections.Generic;
using System.IO;
using ln.logging;
using ln.types;
using System.Linq;
using ln.types.serialize;
using ln.skyscanner.entities;
using System.Net.NetworkInformation;
using ln.snmp;
using ln.snmp.endpoint;
using ln.perfdb;
using ln.perfdb.storage;
using ln.skyscanner.check;
using System.Threading;
using ln.snmp.types;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using ln.types.odb;
using ln.skyscanner.crawl.service;
using ln.skyscanner.crawl.tests;
using LiteDB;
using ln.types.net;
namespace ln.skyscanner.crawl
@ -43,12 +32,12 @@ namespace ln.skyscanner.crawl
CrawlService.RegisterService(new SNMP(new string[] { "VhclfC7lfIojYZ", "Vhclf(C7$lfIojYZ", "ByFR4oW98hap", "qVy3hnZJ2fov" }));
CrawlService.RegisterService(new RFC1213());
CrawlService.RegisterService(new HTTP());
CrawlService.RegisterService(new SSH());
}
public SkyScanner SkyScanner { get; }
public String BasePath { get; set; }
public String PerfPath => Path.Combine(BasePath, "perfdb");
public string PoolPath => Path.Combine(BasePath, "pool");
public String DBFileName => Path.Combine(PoolPath, "crawler.db");
@ -86,8 +75,6 @@ namespace ln.skyscanner.crawl
if (!Directory.Exists(BasePath))
Directory.CreateDirectory(BasePath);
if (!Directory.Exists(PerfPath))
Directory.CreateDirectory(PerfPath);
if (!Directory.Exists(PoolPath))
Directory.CreateDirectory(PoolPath);
@ -173,7 +160,10 @@ namespace ln.skyscanner.crawl
public void EnsureSubnet(Network4 network)
{
FindSubnet(network);
lock (this)
{
FindSubnet(network);
}
}
public void Enqueue(JobDelegate job)

View File

@ -67,7 +67,6 @@ namespace ln.skyscanner.crawl.service
}
catch (WebException e)
{
Logging.Log(e);
}
}
return false;

View File

@ -13,9 +13,10 @@ using ln.types;
using Renci.SshNet.Common;
using System.Net.Sockets;
using ln.types.net;
using ln.skyscanner.crawl.service;
namespace ln.skyscanner.crawl.tests
{
public static class SSH
public class SSH : CrawlService
{
static string[] defaultPasswords = new string[]
{
@ -34,6 +35,10 @@ namespace ln.skyscanner.crawl.tests
"DVqxof1JQ9at"
};
public SSH()
: base("ssh")
{
}
public static bool CanConnect(CrawledHost crawledHost)
{
@ -81,22 +86,6 @@ namespace ln.skyscanner.crawl.tests
private static bool CanConnect(CrawledHost crawledHost, IPv4 host, int port, string username, string password,bool throwe = false)
{
using (TcpClient tcp = new TcpClient())
{
try
{
tcp.Connect(host.ToString(), port);
if (!tcp.Connected)
return false;
tcp.Close();
} catch (SocketException)
{
if (throwe)
throw;
return false;
}
}
using (SshClient client = new SshClient(host.ToString(), port, username, password))
{
client.ConnectionInfo.Timeout = TimeSpan.FromSeconds(1);
@ -124,7 +113,15 @@ namespace ln.skyscanner.crawl.tests
return false;
}
public override bool Check(Crawl crawl)
{
return CanConnect(crawl.Host);
}
public override bool HostProvidesOption(Crawl crawl, params object[] parameters)
{
return crawl.Host.GetHint<IPv4>("ssh.ip", null) != null;
}
}
}

View File

@ -0,0 +1,50 @@
// /**
// * File: Ubiquity.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 System.Linq;
using ln.snmp.endpoint;
using ln.skyscanner.crawl.tests;
using ln.snmp;
using System.Collections.Generic;
using ln.snmp.types;
namespace ln.skyscanner.crawl.service
{
public class Ubiquity : CrawlService
{
public Ubiquity()
: base("ubiquity")
{
}
public override bool Check(Crawl crawl)
{
if (crawl.CheckRequiredOption("snmp"))
{
using (SnmpInterface snmp = SNMP.GetSnmpInterface(crawl.Host))
{
if (crawl.Host.GetHint("snmp.orids", new string[0]).Contains("1.3.6.1.4.1.41112"))
{
List<Sequence> test = snmp.snmpWalk("1.3.6.1.4.1.41112.1.3.2.1.11");
List<Sequence> test2 = snmp.snmpWalk("1.3.6.1.4.1.41112.1.3.3.1.66");
crawl.Host.SetHint("ubiquity.ptp", true);
}
}
}
return false;
}
public override bool HostProvidesOption(Crawl crawl, params object[] parameters)
{
return false;
}
}
}

View File

@ -43,8 +43,6 @@ namespace ln.skyscanner.entities
public void EnsureSubnet(Network4 network)
{
SkyScanner.Crawler.EnsureSubnet(network);
Subnet subnet = SkyEntities.subnetCollection.Where(s => s.Network.Equals(network)).FirstOrDefault();
if (subnet == null)
{

View File

@ -48,7 +48,11 @@ namespace ln.skyscanner.entities
[JsonIgnore]
public IEnumerable<Subnet> Subnets => SkyScanner.Instance.Entities.subnetCollection.Select("Network", Networks.Select(net => net.Network));
public String UniqueIdentity => PrimaryIP.ToString();
public String[] Checks => checks.ToArray();
private HashSet<URI> uris = new HashSet<URI>();
private HashSet<string> checks = new HashSet<string>();
private Node()
{
@ -61,6 +65,13 @@ namespace ln.skyscanner.entities
Created = DateTime.Now;
}
public bool AddCheck(string perfName)
{
if (checks == null)
checks = new HashSet<string>();
return checks.Add(perfName);
}
public void RemoveURI(string scheme)
{
RemoveURI(FindURIs(scheme));

101
http/CheckerApi.cs 100644
View File

@ -0,0 +1,101 @@
// /**
// * File: CheckerApi.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 System.Collections.Generic;
using ln.http;
using ln.http.resources;
using ln.types.threads;
using ln.perfdb.storage;
using Newtonsoft.Json;
namespace ln.skyscanner.http
{
public class CheckerApi : JsonCallResource
{
public CheckerApi(Resource container)
: base(container, "checker")
{
new Checks(this);
}
[Callable]
public PoolJob[] CurrentPoolJobs => SkyScanner.Instance.Checker.CurrentJobs;
[Callable]
public PoolJob[] QueuedPoolJobs => SkyScanner.Instance.Checker.QueuedJobs;
class Checks : BaseResource
{
public Checks(CheckerApi container)
:base(container,"checks")
{ }
public override bool Contains(string name)
{
return base.Contains(name) || SkyScanner.Instance.Checker.ContainsPerfFile(name);
}
public override Resource GetResource(string name)
{
if (base.Contains(name))
return base.GetResource(name);
if (SkyScanner.Instance.Checker.ContainsPerfFile(name))
{
return new Check(this, name);
}
throw new KeyNotFoundException();
}
public override HttpResponse GetResponse(HttpRequest httpRequest)
{
HttpResponse response = new HttpResponse(httpRequest);
response.SetHeader("content-type", "application/json");
response.ContentWriter.Write(JsonConvert.SerializeObject(SkyScanner.Instance.Checker.PerfNames));
return response;
}
class Check : Resource
{
public Check(Checks container,String perfName)
:base(container,perfName)
{}
public override void AddResource(Resource resource) => throw new NotImplementedException();
public override bool Contains(string name) => throw new NotImplementedException();
public override IEnumerable<Resource> GetResources() => throw new NotImplementedException();
public override void RemoveResource(Resource resource) => throw new NotImplementedException();
public override HttpResponse GetResponse(HttpRequest httpRequest)
{
PerfFile perfFile = SkyScanner.Instance.Checker.GetPerfFile(Name);
PerfValue[] perfValues = null;
lock (perfFile)
{
perfFile.EnsureOpen();
perfValues = perfFile.QueryTime((int)(TimeSpan.FromHours(1).TotalSeconds), 0);
perfFile.Close();
}
HttpResponse response = new HttpResponse(httpRequest);
response.SetHeader("content-type", "application/json");
response.ContentWriter.Write(JsonConvert.SerializeObject(perfValues));
return response;
}
}
}
}
}

View File

@ -17,6 +17,7 @@ namespace ln.skyscanner.http
new SkyScannerHttpManagement(this,SkyScanner);
new CrawlerApi(this, SkyScanner);
new NetworkApi(this);
new CheckerApi(this);
}

View File

@ -56,7 +56,7 @@
<Compile Include="entities\Subnet.cs" />
<Compile Include="entities\NetworkInterface.cs" />
<Compile Include="Check.cs" />
<Compile Include="check\Hostalive.cs" />
<Compile Include="checks\Hostalive.cs" />
<Compile Include="SkyScanner.cs" />
<Compile Include="http\SkyScannerHttpApplication.cs" />
<Compile Include="http\SkyScannerHttpApi.cs" />
@ -77,6 +77,11 @@
<Compile Include="crawl\service\TCP.cs" />
<Compile Include="entities\ConfiguredIP.cs" />
<Compile Include="crawl\service\HTTP.cs" />
<Compile Include="crawl\service\Ubiquity.cs" />
<Compile Include="checks\SkyChecker.cs" />
<Compile Include="checks\SkyCheck.cs" />
<Compile Include="checks\CheckJob.cs" />
<Compile Include="http\CheckerApi.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
@ -147,10 +152,19 @@
<None Include="templates\static\network\hoptable.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\css\Chart.min.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\dist\Chart.min.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\checks\index.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Folder Include="identify\" />
<Folder Include="check\" />
<Folder Include="checks\" />
<Folder Include="entities\" />
<Folder Include="crawl\" />
<Folder Include="http\" />
@ -160,6 +174,8 @@
<Folder Include="templates\static\css\" />
<Folder Include="crawl\service\" />
<Folder Include="templates\static\network\" />
<Folder Include="http\check\" />
<Folder Include="templates\static\checks\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ln.snmp\ln.snmp.csproj">

View File

@ -0,0 +1,73 @@
<%frame "frame.html"%>
<h1>Checks</h1>
<div class="flex row">
<div>
<select size="25" id="perfList"></select>
</div>
<div>
<canvas id="perfChart" width="1000" height="500"></canvas>
</div>
</div>
<script type="text/javascript">
moment.defaultFormat = "DD.MM.YYYY HH:mm";
var chartCTX = $("#perfChart");
var chart = new Chart( chartCTX, {
type: 'bar',
data: {
datasets: [
{
label: "-",
data: []
}
]
},
options: {
scales: {
xAxes: [{
type: 'time',
time: {
unit: "minute",
tooltipFormat: "DD.MM.YYYY HH:mm",
displayFormats: {
minute: "DD.MM.YYYY HH:mm"
},
parser: moment.unix
}
}]
}
}
} );
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 } );
};
});
chart.update();
});
});
</script>

View File

@ -0,0 +1 @@
@keyframes chartjs-render-animation{from{opacity:.99}to{opacity:1}}.chartjs-render-monitor{animation:chartjs-render-animation 1ms}.chartjs-size-monitor,.chartjs-size-monitor-expand,.chartjs-size-monitor-shrink{position:absolute;direction:ltr;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1}.chartjs-size-monitor-expand>div{position:absolute;width:1000000px;height:1000000px;left:0;top:0}.chartjs-size-monitor-shrink>div{position:absolute;width:200%;height:200%;left:0;top:0}

File diff suppressed because one or more lines are too long

View File

@ -6,7 +6,8 @@
<link href="/static/css/jquery-ui.min.css" rel="stylesheet" />
<link href="/static/css/datatables.min.css" rel="stylesheet" />
<link href="/static/css/Chart.min.css" rel="stylesheet" />
<link href="/static/css/style.css" rel="stylesheet" />
<script type="text/javascript" src="/static/skyapi.js"></script>
@ -16,6 +17,7 @@
<script type="text/javascript" src="/static/dist/moment-with-locales.js"></script>
<script type="text/javascript" src="/static/dist/datatables.min.js"></script>
<script type="text/javascript" src="/static/dist/percentageBars.js"></script>
<script type="text/javascript" src="/static/dist/Chart.min.js"></script>
</head>
<body>
<script type="text/javascript">

View File

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