broken
Harald Wolff 2019-09-16 20:29:52 +02:00
parent e8b7eda522
commit 1d9a61ec51
75 changed files with 1440 additions and 926 deletions

View File

@ -1,14 +1,7 @@
using System;
using ln.logging;
using ln.http;
using System.Net;
using ln.skyscanner.http;
using System.IO;
using ln.types.threads;
using ln.skyscanner.checks;
using ln.skyscanner.import.skytron;
using System.Linq;
using ln.skyscanner.entities;
using ln.types.net;
using ln.application;
using ln.application.service;
@ -114,23 +107,19 @@ namespace ln.skyscanner
public override void ServiceMain(IApplicationInterface applicationInterface)
{
String BasePath = ".";
Resource rootResource = applicationInterface.HTTPApplication.RootResource;
String TemplatesBasePath = Path.Combine(BasePath, "templates", "static");
/* Development hint */
if (Directory.Exists("../../templates/static"))
TemplatesBasePath = Path.Combine(BasePath, "..", "..", "templates", "static");
DirectoryResource staticTemplates = new DirectoryResource(rootResource, TemplatesBasePath);
DirectoryResource staticTemplates = new DirectoryResource(new string[] { "../../www", "www" });
staticTemplates.ResourceTypeHook = ResourceTypeHook;
staticTemplates.DefaultResource = staticTemplates.GetResource("index.html");
staticTemplates.FallBackResource = staticTemplates.DefaultResource;
rootResource.DefaultResource = staticTemplates;
staticTemplates.GetResource("vue").DefaultResource = staticTemplates.GetResource("vue").GetResource("vue.html");
staticTemplates.GetResource("vue").FallBackResource = staticTemplates.GetResource("vue").DefaultResource;
webSocketInterface = new ApplicationWebSocket(rootResource, "socket", RPCContainer);
applicationInterface.HTTPApplication.RootResource = staticTemplates;
webSocketInterface = new ApplicationWebSocket(null, "socket", RPCContainer);
staticTemplates.InjectResource(webSocketInterface);
RPCContainer.Add("", new SkyScannerRpc(this));
RPCContainer.Add("ServiceContainer",applicationInterface.ServiceContainer.RPC);

View File

@ -71,7 +71,7 @@ namespace ln.skyscanner.checks
foreach (Sequence[] battery in batteries)
{
node.WritePerformanceValue(checkService.PerformanceValueService, Name, String.Format("ups_battery_{0}_status", n), (double)((Integer)(battery[0].Items[1])).LongValue);
node.WritePerformanceValue(checkService.PerformanceValueService, Name, String.Format("ups_battery_{0}_minutes_remain", n), (double)((Integer)(battery[1].Items[1])).LongValue, wLower: 20, cLower: 10 );
node.WritePerformanceValue(checkService.PerformanceValueService, Name, String.Format("ups_battery_{0}_minutes_remain", n), (double)((Integer)(battery[1].Items[1])).LongValue, wLower: 20, cLower: 10);
node.WritePerformanceValue(checkService.PerformanceValueService, Name, String.Format("ups_battery_{0}_capacity", n), (double)((Integer)(battery[2].Items[1])).LongValue, wLower: 75, cLower: 50);
node.WritePerformanceValue(checkService.PerformanceValueService, Name, String.Format("ups_battery_{0}_voltage", n), (double)((Integer)(battery[3].Items[1])).LongValue / 10.0);
node.WritePerformanceValue(checkService.PerformanceValueService, Name, String.Format("ups_battery_{0}_temperature", n), (double)((Integer)(battery[4].Items[1])).LongValue, wUpper: 40, cUpper: 60);
@ -80,6 +80,8 @@ namespace ln.skyscanner.checks
checkState.CheckState = CheckState.OK;
return;
} catch (TimeoutException)
{
} catch (SnmpError)
{
}

View File

@ -49,11 +49,32 @@ namespace ln.skyscanner.checks
float fSuccess = (float)success / (float)n;
node.WritePerformanceValue(checkService.PerformanceValueService, Name, "replies", fSuccess, node.DeviceType == DeviceType.UNKNOWN ? Double.MinValue : 0.8, double.MaxValue, node.DeviceType == DeviceType.UNKNOWN ? Double.MinValue : 0.6, double.MaxValue);
if (success > 0)
node.WritePerformanceValue(
checkService.PerformanceValueService,
Name,
"replies",
fSuccess,
node.DeviceType == DeviceType.UNKNOWN ? Double.MinValue : 0.8,
double.MaxValue,
node.DeviceType == DeviceType.UNKNOWN ? Double.MinValue : 0.6,
double.MaxValue,
"%"
);
if (success > 0)
{
roundTripTime /= success;
node.WritePerformanceValue(checkService.PerformanceValueService, Name, "rta", roundTripTime, 0, 80, 0, 140);
node.WritePerformanceValue(
checkService.PerformanceValueService,
Name,
"rta",
roundTripTime,
0,
80,
0,
140,
"ms"
);
}
foreach (PerformanceValue pv in checkState.PerformanceValues)

View File

@ -38,10 +38,8 @@ namespace ln.skyscanner.checks
double sig = (sigData[n][0].Items[1] as Integer).LongValue / 10.0;
double snr = (sigData[n][1].Items[1] as Integer).LongValue / 10.0;
node.WritePerformanceValue(checkService.PerformanceValueService, Name, String.Format("ptp_rx_pwr_{0}",n), sig, -75.0, 0, -80.0, 0);
node.WritePerformanceValue(checkService.PerformanceValueService, Name, String.Format("ptp_rx_snr_{0}",n), snr, 12, 99, 8, 99);
node.WritePerformanceValue(checkService.PerformanceValueService, Name, String.Format("ptp_rx_pwr_{0}",n), sig, -75.0, 0, -80.0, 0,"dBm",n.ToString());
node.WritePerformanceValue(checkService.PerformanceValueService, Name, String.Format("ptp_rx_snr_{0}",n), snr, 12, 99, 8, 99,"dB", n.ToString());
}
}

View File

@ -61,6 +61,8 @@ namespace ln.skyscanner.checks
public CheckStateChange[] History => history.ToArray();
List<CheckStateChange> history = new List<CheckStateChange>();
public string Message { get; set; }
protected SkyCheckState()
{
}

View File

@ -90,12 +90,12 @@ namespace ln.skyscanner.crawl
Crawler.FindHostForIP(ip);
}
if (AbortRequested)
if (JobAbortRequested)
break;
}
if (!AbortRequested)
if (!JobAbortRequested)
{
Subnet.LastScan = startTime;
Subnet.NextScan = startTime + TimeSpan.FromHours(24);

View File

@ -145,7 +145,7 @@ namespace ln.skyscanner.entities
// performanceValues[Name] = performanceValue;
//}
public void WritePerformanceValue(PerformanceValueService performanceValueService, String checkName, String perfName, double value, double wLower = Double.MinValue, double wUpper = Double.MaxValue, double cLower = Double.MinValue, double cUpper = Double.MaxValue)
public void WritePerformanceValue(PerformanceValueService performanceValueService, String checkName, String perfName, double value, double wLower = Double.MinValue, double wUpper = Double.MaxValue, double cLower = Double.MinValue, double cUpper = Double.MaxValue,String perfUnit = "",String group = "",double exMin = double.MinValue,double exMax = double.MaxValue)
{
string[] perfPath = new string[] { UniqueIdentity, checkName, perfName };
perfName = string.Join("/", perfPath);
@ -157,6 +157,12 @@ namespace ln.skyscanner.entities
performanceValue = new PerformanceValue(perfPath, wLower, wUpper, cLower, cUpper);
skyCheckState.AddPerformanceValue(performanceValue);
}
performanceValue.PerfUnit = perfUnit;
performanceValue.Group = group;
performanceValue.ExpectedMinimum = exMin;
performanceValue.ExpectedMaximum = exMax;
performanceValueService.WriteValue(performanceValue, value);
}

View File

@ -95,135 +95,6 @@
<Compile Include="perfvalue\PerformanceValue.cs" />
</ItemGroup>
<ItemGroup>
<None Include="templates\static\index.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\frame.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\skyapi.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\workspace.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\tables.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\css\style.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\dist\moment-with-locales.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\nav.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\css\jquery-ui.min.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\dist\jquery-ui.min.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\dist\jquery.min.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\log.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\css\select.jqueryui.min.css" />
<None Include="templates\static\dist\datatables.min.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\dist\dataTables.select.min.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\dist\select.jqueryui.min.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\css\datatables.min.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\dist\percentageBars.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\network\index.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<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>
<None Include="templates\static\checks\status.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\checks\checkstates.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\topnav.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\system\index.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\network\pops.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\css\index.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\css\images\ui-icons_444444_256x240.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\css\images\ui-icons_555555_256x240.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\css\images\ui-icons_777620_256x240.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\css\images\ui-icons_777777_256x240.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\css\images\ui-icons_cc0000_256x240.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\css\images\ui-icons_ffffff_256x240.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\css\images\ui-icons_6495ED_256x240.png" />
<None Include="templates\static\checks\issues.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\crawler\hosts.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\crawler\subnets.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\crawler\status.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\checks\checks.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\network\l2segments.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\checks\issues2.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\checks\node.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="templates\static\dist\moment-timezone-with-data.js" />
<None Include="crawl\Crawler.cs" />
<None Include="crawl\CrawledHost.cs" />
<None Include="crawl\CrawlNetwork.cs" />
@ -239,6 +110,170 @@
<None Include="crawl\service\TCP.cs" />
<None Include="crawl\service\Ubiquity.cs" />
<None Include="packages.config" />
<None Include="www\checks\checks.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\checks\checkstates.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\checks\index.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\checks\issues.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\checks\issues2.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\checks\node.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\checks\status.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\crawler\hosts.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\crawler\status.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\crawler\subnets.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\css\Chart.min.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\css\datatables.min.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\css\images\ui-icons_444444_256x240.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\css\images\ui-icons_555555_256x240.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\css\images\ui-icons_6495ED_256x240.png" />
<None Include="www\css\images\ui-icons_777620_256x240.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\css\images\ui-icons_777777_256x240.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\css\images\ui-icons_cc0000_256x240.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\css\images\ui-icons_ffffff_256x240.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\css\index.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\css\jquery-ui.min.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\css\select.jqueryui.min.css" />
<None Include="www\css\style.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\dist\Chart.min.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\dist\datatables.min.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\dist\dataTables.select.min.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\dist\jquery.min.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\dist\jquery-ui.min.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\dist\moment-timezone-with-data.js" />
<None Include="www\dist\moment-with-locales.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\dist\percentageBars.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\dist\select.jqueryui.min.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\frame.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\index.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\log.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\nav.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\network\hoptable.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\network\index.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\network\l2segments.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\network\pops.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\skyapi.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\system\index.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\tables.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\topnav.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\workspace.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\css\ln.application.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\vue\vue.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\vue\ln.skyscanner.js" />
<None Include="www\vue\page.layout.css" />
<None Include="www\vue\ln.skyscanner.issues.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\vue\ln.skyscanner.system.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\ln.tools.js" />
<None Include="www\vue\ln.skyscanner.system.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\vue\tables.layout.css" />
<None Include="www\vue\ln.skyscanner.nodes.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\vue\ln.skyscanner.nodes.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\vue\ln.skyscanner.node.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\vue\ln.skyscanner.node.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\vue\ln.skyscanner.issues.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\vue\ln.skyscanner.graphs.js" />
</ItemGroup>
<ItemGroup>
<Folder Include="identify\" />
@ -246,21 +281,15 @@
<Folder Include="entities\" />
<Folder Include="crawl\" />
<Folder Include="http\" />
<Folder Include="templates\" />
<Folder Include="templates\static\" />
<Folder Include="templates\static\dist\" />
<Folder Include="templates\static\css\" />
<Folder Include="crawl\service\" />
<Folder Include="templates\static\network\" />
<Folder Include="http\check\" />
<Folder Include="templates\static\checks\" />
<Folder Include="templates\static\system\" />
<Folder Include="templates\static\crawler\" />
<Folder Include="import\" />
<Folder Include="import\skytron\" />
<Folder Include="devices\" />
<Folder Include="services\" />
<Folder Include="perfvalue\" />
<Folder Include="www\" />
<Folder Include="www\vue\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ln.snmp\ln.snmp.csproj">

View File

@ -27,6 +27,13 @@ namespace ln.skyscanner.perfvalue
public bool IgnoreLimits;
public String PerfUnit { get; set; } = String.Empty;
public String Group { get; set; } = String.Empty;
public double ExpectedMaximum { get; set; } = double.MaxValue;
public double ExpectedMinimum { get; set; } = double.MinValue;
private PerformanceValue()
{
}

View File

@ -51,9 +51,10 @@ namespace ln.skyscanner.services
checkPool = new Pool(96);
checkPool.PoolJobFinished += PoolJobFinished;
checkPool.Start();
SNMPEngine = new SNMPEngine();
SNMPEngine.Timeout = 2000;
SNMPEngine.Timeout = 5000;
long nextMinute = DateTimeOffset.Now.ToUnixTimeMilliseconds();
@ -100,12 +101,18 @@ namespace ln.skyscanner.services
}
}
checkPool.Abort();
Logging.Log(LogLevel.INFO, "CheckService: Aborting currently scheduled checks");
checkPool.Stop(true);
SNMPEngine.Close();
coreService.RPCContainer.Remove("CheckService");
entityService = null;
performanceValueService = null;
coreService = null;
Logging.Log(LogLevel.INFO, "CheckService: stopped");
}
private void UpdateNodeList()

View File

@ -43,7 +43,12 @@ namespace ln.skyscanner.services
{
lock (this)
{
Monitor.Wait(this);
try
{
Monitor.Wait(this);
} catch (ThreadInterruptedException)
{
}
}
}

71
skyscanner.sln 100644
View File

@ -0,0 +1,71 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.http", "..\ln.http\ln.http.csproj", "{CEEEEB41-3059-46A2-A871-2ADE22C013D9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.templates", "..\ln.templates\ln.templates.csproj", "{AD0267BB-F08C-4BE1-A88D-010D49041761}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.http.resources", "..\ln.http.resources\ln.http.resources.csproj", "{F9086FE4-8925-42FF-A59C-607341604293}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.snmp", "..\ln.snmp\ln.snmp.csproj", "{C7A43B82-55F2-4092-8DBE-6BE29CBF079D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.skyscanner", "ln.skyscanner.csproj", "{8456AFA0-20E9-4566-A81A-3C0EDB12356F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.perfdb", "..\ln.perfdb\ln.perfdb.csproj", "{D934C1E8-9215-4D8D-83B3-A296E4912792}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.logging", "..\ln.logging\ln.logging.csproj", "{D471A566-9FB6-41B2-A777-3C32874ECD0E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.types", "..\ln.types\ln.types.csproj", "{8D9AB9A5-E513-4BA7-A450-534F6456BF28}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.application", "..\ln.application\ln.application.csproj", "{44AA3A50-7214-47F2-9D60-6FF34C0FE6D3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.json", "..\ln.json\ln.json.csproj", "{D9342117-3249-4D8B-87C9-51A50676B158}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x86 = Debug|x86
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{CEEEEB41-3059-46A2-A871-2ADE22C013D9}.Debug|x86.ActiveCfg = Debug|Any CPU
{CEEEEB41-3059-46A2-A871-2ADE22C013D9}.Debug|x86.Build.0 = Debug|Any CPU
{CEEEEB41-3059-46A2-A871-2ADE22C013D9}.Release|x86.ActiveCfg = Release|Any CPU
{CEEEEB41-3059-46A2-A871-2ADE22C013D9}.Release|x86.Build.0 = Release|Any CPU
{AD0267BB-F08C-4BE1-A88D-010D49041761}.Debug|x86.ActiveCfg = Debug|Any CPU
{AD0267BB-F08C-4BE1-A88D-010D49041761}.Debug|x86.Build.0 = Debug|Any CPU
{AD0267BB-F08C-4BE1-A88D-010D49041761}.Release|x86.ActiveCfg = Release|Any CPU
{AD0267BB-F08C-4BE1-A88D-010D49041761}.Release|x86.Build.0 = Release|Any CPU
{F9086FE4-8925-42FF-A59C-607341604293}.Debug|x86.ActiveCfg = Debug|Any CPU
{F9086FE4-8925-42FF-A59C-607341604293}.Debug|x86.Build.0 = Debug|Any CPU
{F9086FE4-8925-42FF-A59C-607341604293}.Release|x86.ActiveCfg = Release|Any CPU
{F9086FE4-8925-42FF-A59C-607341604293}.Release|x86.Build.0 = Release|Any CPU
{C7A43B82-55F2-4092-8DBE-6BE29CBF079D}.Debug|x86.ActiveCfg = Debug|Any CPU
{C7A43B82-55F2-4092-8DBE-6BE29CBF079D}.Debug|x86.Build.0 = Debug|Any CPU
{C7A43B82-55F2-4092-8DBE-6BE29CBF079D}.Release|x86.ActiveCfg = Release|Any CPU
{C7A43B82-55F2-4092-8DBE-6BE29CBF079D}.Release|x86.Build.0 = Release|Any CPU
{8456AFA0-20E9-4566-A81A-3C0EDB12356F}.Debug|x86.ActiveCfg = Debug|x86
{8456AFA0-20E9-4566-A81A-3C0EDB12356F}.Debug|x86.Build.0 = Debug|x86
{8456AFA0-20E9-4566-A81A-3C0EDB12356F}.Release|x86.ActiveCfg = Release|x86
{8456AFA0-20E9-4566-A81A-3C0EDB12356F}.Release|x86.Build.0 = Release|x86
{D934C1E8-9215-4D8D-83B3-A296E4912792}.Debug|x86.ActiveCfg = Debug|Any CPU
{D934C1E8-9215-4D8D-83B3-A296E4912792}.Debug|x86.Build.0 = Debug|Any CPU
{D934C1E8-9215-4D8D-83B3-A296E4912792}.Release|x86.ActiveCfg = Release|Any CPU
{D934C1E8-9215-4D8D-83B3-A296E4912792}.Release|x86.Build.0 = Release|Any CPU
{D471A566-9FB6-41B2-A777-3C32874ECD0E}.Debug|x86.ActiveCfg = Debug|Any CPU
{D471A566-9FB6-41B2-A777-3C32874ECD0E}.Debug|x86.Build.0 = Debug|Any CPU
{D471A566-9FB6-41B2-A777-3C32874ECD0E}.Release|x86.ActiveCfg = Release|Any CPU
{D471A566-9FB6-41B2-A777-3C32874ECD0E}.Release|x86.Build.0 = Release|Any CPU
{8D9AB9A5-E513-4BA7-A450-534F6456BF28}.Debug|x86.ActiveCfg = Debug|Any CPU
{8D9AB9A5-E513-4BA7-A450-534F6456BF28}.Debug|x86.Build.0 = Debug|Any CPU
{8D9AB9A5-E513-4BA7-A450-534F6456BF28}.Release|x86.ActiveCfg = Release|Any CPU
{8D9AB9A5-E513-4BA7-A450-534F6456BF28}.Release|x86.Build.0 = Release|Any CPU
{44AA3A50-7214-47F2-9D60-6FF34C0FE6D3}.Debug|x86.ActiveCfg = Debug|Any CPU
{44AA3A50-7214-47F2-9D60-6FF34C0FE6D3}.Debug|x86.Build.0 = Debug|Any CPU
{44AA3A50-7214-47F2-9D60-6FF34C0FE6D3}.Release|x86.ActiveCfg = Release|Any CPU
{44AA3A50-7214-47F2-9D60-6FF34C0FE6D3}.Release|x86.Build.0 = Release|Any CPU
{D9342117-3249-4D8B-87C9-51A50676B158}.Debug|x86.ActiveCfg = Debug|Any CPU
{D9342117-3249-4D8B-87C9-51A50676B158}.Debug|x86.Build.0 = Debug|Any CPU
{D9342117-3249-4D8B-87C9-51A50676B158}.Release|x86.ActiveCfg = Release|Any CPU
{D9342117-3249-4D8B-87C9-51A50676B158}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal

View File

@ -1,343 +0,0 @@
var LN = (function(){
var appInterface;
var defaultOptions = {
url: null,
};
class LNInterface {
constructor(opt){
var self = this;
this.options = {}
Object.assign(this.options,opt);
if (this.options.url == null)
this.options.url = this.constructURL();
this.rpcCallbacks = [];
this.rpcNextID = 1;
this.websocket = new WebSocket(this.options.url);
this.websocket.onerror = function(e){
alert("WebSocket caught error: " + e.date);
}
this.websocket.onmessage = function(e){
try{
var j = JSON.parse(e.data);
if (j.state){
updateState(j.state);
} else if (j.id)
{
for (var n=0;n<self.rpcCallbacks.length;n++)
{
if (self.rpcCallbacks[n].id == j.id)
{
if (j.error)
{
console.log("RPCResult with error received: " + JSON.stringify(j.error));
}
self.rpcCallbacks[n].cbfn(j.result,j.error);
self.rpcCallbacks.splice(n,1);
return;
}
}
}
} catch(exc){
console.log(exc);
console.log("websocket malformed message: " + (e.data));
$("<textarea></textarea>").text(e.data).appendTo($(body));
}
}
}
rpc(module,method,parameters,cbfn){
var rpcCall = {
module: module,
method: method,
parameters: parameters,
id: this.rpcNextID++,
};
if (this.websocket.readyState != 1)
{
setTimeout(function(){
LN().rpc(module,method,parameters,cbfn);
},250);
} else {
this.rpcCallbacks.push( { id: rpcCall.id, cbfn: cbfn } );
this.websocket.send(
JSON.stringify(rpcCall)
);
}
}
constructURL(){
var pageURI = window.location;
var scheme = pageURI.scheme == "https" ? "wss:" : "ws:";
var host = pageURI.host;
return scheme + "//" + host + "/socket";
}
}
return function(options){
if (!appInterface)
appInterface = new LNInterface(options);
return appInterface;
};
})();
/*
Object.values = function(o) {
var values = [];
for(var property in o) {
values.push(o[property]);
}
return values;
}
function encodeID( t )
{
return ("" + t).replace( /[\.\/]/g, "_");
}
var lagDetector = null;
function updateState(state)
{
try
{
if (lagDetector)
clearTimeout(lagDetector);
$("#ServerTime").text("ServerTime: " + moment(state.currentTime).format());
lagDetector = setTimeout(function(){
$("#ServerTime").text("Server lag detected");
}, 2000);
} catch (e)
{
$("#ServerTime").text("Server state unexpected!");
}
}
function SKYAPI(baseurl){
this.baseurl = baseurl;
this.refresh = []
this.websocket = new WebSocket("ws://localhost:8080/socket");
this.websocket.onerror = function(e){
alert("WebSocket Error: " + e);
}
this.websocket.onmessage = function(e){
var j = JSON.parse(e.data);
if (j.state){
updateState(j.state);
}
}
this.setBaseURL = function(url){ this.baseurl = url; }
this.addRefresh = function( rh, seconds = null ){ this.refresh.push( { interval: seconds ? seconds : 5, refresh: rh } ); }
this.get = function(page, json, handler = null){ return this.__request("GET", page, json, handler); }
this.post = function(page, json, handler = null){ return this.__request("POST", page, json, handler); }
this.put = function(page, json, handler = null){ return this.__request("PUT", page, json, handler); }
this.__request = function(method, page, json, handler = null){
if (page[0] == '/')
page = page.substr(1);
var x = new XMLHttpRequest();
if (handler != null)
{
x.onload = function(){
var responseText = x.responseText;
if (json && !content)
handler( JSON.parse( responseText ) );
else
handler( responseText );
}
}
x.open(method, this.baseurl + page);
if (json)
x.send(JSON.stringify(json));
else
x.send();
}
this.getJson = function(page, handler){
var j = function(t){
handler(JSON.parse(t));
};
return this.get( page, null, j );
}
this.call = function(endpoint,method,parameters = [], receiver = null){
var x = new XMLHttpRequest();
x.open("POST", this.baseurl + endpoint, (receiver != null));
x.setRequestHeader("content-type","application/json");
if (receiver)
{
x.onload = function(){ var r = JSON.parse(this.responseText).Result; receiver(r); }
x.onerror = function(){ receiver(false); }
}
var methodCall = {
"MethodName": method,
"Parameters": parameters
}
x.send(JSON.stringify(methodCall));
if (!receiver)
{
var result = JSON.parse(x.responseText);
if (result.Exception != null)
throw result.Exception;
return result.Result;
}
return x;
}
this.loadPage = function (page) {
if (page[0] == '/')
page = page.substr(1);
var x = new XMLHttpRequest();
x.open("GET", this.baseurl + page);
x.setRequestHeader("x-template-unframed","unframed");
x.onload = function()
{
$("#content").empty();
$("#content").append(this.responseText);
history.pushState(null, page, skyapi().baseurl + page);
}
this.refresh = []
x.send();
return false;
}
this.fireOnLoad = function(element){
if (element.onload != null)
{
element.onload();
}
for (var n=0;n<element.children.length;n++)
this.fireOnLoad(element.children[n]);
}
this.__refresh_index = 0;
this.UIRefresh = function(){
this.__refresh_index++;
for (var n=0;n<this.refresh.length;n++)
{
var r = this.refresh[n];
if ((this.__refresh_index % r.interval)==0)
r.refresh();
}
}
setInterval( function(){ skyapi().UIRefresh(); }, 1000 );
}
function showStatistics(stats)
{
try
{
$("#ServerTime").text("ServerTime: " + stats.ServerTime);
$("#indHttpServer").attr("state",stats.States.HttpServer);
$("#indManager").attr("state",stats.States.Manager);
$("#indCrawler").attr("state",stats.States.Crawler);
$("#indChecks").attr("state",stats.States.Checks);
$("#indDispatcher").attr("state",stats.States.Dispatcher);
$("#indHttpServer").attr("title",stats.States.HttpServer);
$("#indManager").attr("title",stats.States.Manager);
$("#indCrawler").attr("title",stats.States.Crawler);
$("#indChecks").attr("title",stats.States.Checks);
$("#indDispatcher").attr("title",stats.States.Dispatcher);
} catch (e)
{
$("#ServerTime").text("Server unreachable");
$("#indHttpServer").attr("state",3);
$("#indManager").attr("state",0);
$("#indCrawler").attr("state",0);
$("#indChecks").attr("state",0);
$("#indDispatcher").attr("state",0);
$("#indHttpServer").attr("title","UNKNOWN");
$("#indManager").attr("title","UNKNOWN");
$("#indCrawler").attr("title","UNKNOWN");
$("#indChecks").attr("title","UNKNOWN");
$("#indDispatcher").attr("title","UNKNOWN");
}
}
function updateStatistics()
{
try
{
var request = skyapi().call("api/management","GetStatistics",[],showStatistics);
} catch (e)
{
showStatistics(false);
}
}
var __skyapi = new SKYAPI("/");
function skyapi()
{
return __skyapi;
}
function ScaleSI(value)
{
if (value > 1000000000)
return ((value / 1000000000) | 0) + "G";
if (value > 1000000)
return ((value / 1000000) | 0) + "M";
if (value > 1000)
return ((value / 1000) | 0) + "k";
return value;
}
*/

View File

@ -1,151 +0,0 @@
<%frame "frame.html"%>
<h1>Network Overview</h1>
<h2>Hosts / Nodes
<span class="ui-icon ui-icon-refresh" onclick="$('#nodeTable').DataTable().ajax.reload(null, false);"></span>
<a href="" onclick="LN().rpc('entities','SyncSkytron',[],function(r,e){}); return false;">Sync with Skytron CRM</a>
</h2>
<div>
<table id="nodeTable"></table>
</div>
<h2>Details</h2>
<div class="flex row">
<fieldset style="max-width: 500px;">
<label for="dName">Bezeichnung</label><input type="text" id="dName"><br>
<label for="dPrimaryIP">Primäre IP</label><input type="text" id="dPrimaryIP"><br>
<label for="dPrimaryMac">Primäre MAC</label><input type="text" id="dPrimaryMac"><br>
<label for="dCreated">Erstellt</label><input type="text" id="dCreated" readonly="true"><br>
<label for="dLastUpdate">Letztes Update</label><input type="text" id="dLastUpdate" readonly="true">
</fieldset>
<fieldset style="max-width: 500px;">
<label for="dVendor">Hersteller</label><input type="text" id="dVendor"><br>
<label for="dProduct">Modell</label><input type="text" id="dProduct"><br>
<label for="dProductLine">Modellzeile</label><input type="text" id="dProductLine"><br>
<label for="dDeviceType">Gerätetyp</label><select id="dDeviceType">
<option value="UNKNOWN">-</option>
<option value="ROUTER">Router</option>
<option value="PTP">PtP</option>
<option value="PTMP">PtmP</option>
<option value="UPS">USV</option>
<option value="SERVER">Server</option>
</select>
<label for="dLocation">Lokalisation</label><input type="text" id="dLocation"><br>
</fieldset>
<fieldset id="dURIs">
</fieldset>
<fieldset>
<select id="dInterfaces" size="12">
</select>
</fieldset>
</div>
<script type="text/javascript">
function showNode(node)
{
if (node == null)
{
$("#dName").prop("disabled", true).val("");
$("#dPrimaryIP").prop("disabled", true).val("");
$("#dPrimaryMac").prop("disabled", true).val("");
$("#dCreated").prop("disabled", true).val("");
$("#dLastUpdate").prop("disabled", true).val("");
$("#dVendor").prop("disabled", true).val("");
$("#dProduct").prop("disabled", true).val("");
$("#dProductLine").prop("disabled", true).val("");
$("#dLocation").prop("disabled", true).val("");
$("#dURIs").empty();
$("#dInterfaces").empty();
$("#dDeviceType").prop("disabled",true).selectmenu().val("");
} else {
$("#dName").prop("disabled", false).val(node.Name);
$("#dPrimaryIP").prop("disabled", true).val(node.PrimaryIP);
$("#dPrimaryMac").prop("disabled", true).val(node.PrimaryMac);
$("#dCreated").prop("disabled", true).val(node.Created);
$("#dLastUpdate").prop("disabled", true).val(node.LastUpdate);
$("#dVendor").prop("disabled", false).val(node.Vendor);
$("#dProduct").prop("disabled", false).val(node.Product);
$("#dProductLine").prop("disabled", false).val(node.ProductLine);
$("#dLocation").prop("disabled", false).val(node.Location.Latitude + " / " + node.Location.Longitude);
$("#dURIs").empty();
$.each( node.URIs, function(){ $("#dURIs").append($("<span>" + this.Scheme + "://" + this.Host + ":" + this.Port + (this.Fragment ? "#" + this.Fragment : "") + "</span><br>")); } );
$("#dInterfaces").empty();
$.each( node.Interfaces, function(){
var intf = this;
$.each( intf.ConfiguredIPs, function(){
$("#dInterfaces").append( $( "<option value='"+ this.Network +"'>" + this.IP + "[ " + intf.Name + " ]</option>" ) );
});
});
$("#dDeviceType").prop("disabled",false).selectmenu().val(this.DeviceType);
}
}
$("#dInterfaces").change( function(e){
skyapi().call("api/network","GetHostsInSubnet", [ $(this).children("option:selected").val() ], function(neighbors){
$("#nodeTable").DataTable().clear().rows.add( neighbors ).draw();
});
});
$("#nodeTable").DataTable({
columns: [
{ title: "", data: null },
{ title: "Bezeichnung", data: "Name" },
{ title: "Primäre IP", data: "PrimaryIP" },
{ title: "Primäre MAC", data: "PrimaryMac" },
{ title: "Erstellt", data: "Created" },
{ title: "Letztes Update", data: "LastUpdate" },
{ title: "Hersteller", data: "Vendor" },
{ title: "Produkt", data: "Product" },
{ title: "Gerätetyp", data: "DeviceType" },
{ title: "Standort", data: "Location", render: function(d,t,r){ return d.Latitude + "/" + d.Longitude; } },
{ title: "UniqueIdentity", data: "UniqueIdentity" }
],
columnDefs: [
{ targets: 0, data: null, defaultContent: "<button>?</button>" }
],
select: "single",
height: 300,
fixedHeader: true,
})
.on( "select", function(e,dt,type,indexes){
if (indexes.length > 0)
{
var selNode = dt.rows( indexes ).data()[0];
showNode(selNode);
};
})
.on( "deselect", function(e,dt,type,indexes){
showNode(null);
});
function refreshNodeTable()
{
}
showNode(null);
//refreshNodeTable();
LN().rpc("entities","GetNodes",[],function(r,e){
console.log("received " + r.length + " nodes");
$("#nodeTable").DataTable()
.clear()
.rows
.add(r)
.draw();
});
</script>

View File

@ -1,87 +0,0 @@
<div class="popup">Netz Status
<div>
<div>
<a href="/static/checks/issues2.html"><div>St&ouml;rf&auml;lle (tabellarisch)</div></a>
</div>
<div>
<a href="/static/checks/issues.html"><div>St&ouml;rf&auml;lle (detailiert)</div></a>
</div>
</div>
</div>
<div class="popup">Netz Struktur
<div>
<div>
<a href="/static/network/nodes.html"><div>Knoten</div></a>
</div>
<div>
<a href="/static/network/pops.html"><div>PoP Liste</div></a>
</div>
<div>
<a href="/static/network/l2segments.html"><div>L2 Segmente</div></a>
</div>
<div>
<a href="/static/network/index.html"><div>PtmP Stationen</div></a>
</div>
<div>
<a href="/static/network/hoptable.html"><div>Topologie: technisch</div></a>
</div>
<div>
<a href="/static/network/hoptable.html"><div>Topologie: geographisch</div></a>
</div>
</div>
</div>
<div class="popup">Crawler
<div>
<div>
<a href="/static/crawler/status.html"><div>Status</div></a>
</div>
<div>
<a href="/static/crawler/hosts.html"><div>Hosts</div></a>
</div>
<div>
<a href="/static/crawler/subnets.html"><div>Subnets</div></a>
</div>
</div>
</div>
<div class="popup">Struktur
<div>
<div>
<a href="/static/network/index.html"><div>Übersicht</div></a>
</div>
<div>
<a href="/static/network/hoptable.html"><div>Hop Table</div></a>
</div>
</div>
</div>
<div class="popup">&Uuml;berwachung
<div>
<div>
<a href="/static/checks/status.html"><div>Status</div></a>
</div>
<div>
<a href="/static/checks/checks.html"><div>Check Parameter</div></a>
</div>
<div>
<a href="/static/checks/index.html"><div>Graphen</div></a>
</div>
<div>
<a href="/static/checks/checkstates.html"><div>Check States</div></a>
</div>
</div>
</div>
<div class="popup">System
<div>
<div>
<a href="/static/system/index.html"><div>Modul Steuerung</div></a>
</div>
<div>
<a href="/static/log.html"><div>Logging</div></a>
</div>
</div>
</div>

View File

@ -35,33 +35,7 @@
var charts = []
var chartTimeout = null;
function ntos(n,l){
n = n.toString();
while (n.length < l){
n = "0" + n;
}
return n;
}
function timespan(value){
var days, hours, minutes, seconds;
value = parseInt(value);
days = parseInt(value / 86400);
value %= 86400;
hours = parseInt(value / 3600);
value %= 3600;
minutes = parseInt(value / 60);
value %= 60;
seconds = parseInt(value);
var r = "";
if (days > 0)
r += `${days}d `;
r += `${ntos(hours,2)}:${ntos(minutes,2)}:${ntos(seconds,2)}`;
return r;
}
@ -100,7 +74,7 @@
.append(
$("<a></a>")
.text(node.Name + " [ "+ node.UniqueIdentity +" ]")
.attr("href","/static/checks/node.html#" + node.ID)
.attr("href","/checks/node.html#" + node.ID)
.attr("target","_blank")
);
@ -192,6 +166,11 @@
//console.log(JSON.stringify(nodes));
if (nodes.length > 500)
{
nodes = nodes.slice(0,1000);
}
$.each( nodes , function(){
updateNode(this);
});

View File

@ -7,13 +7,13 @@
Sender: <span id="sender"></span><br>
</div>
<div class="grow">
<a href="" class="protolink">
<a href="" target="_blank" class="protolink" id="link-http">
<div>HTTP:</div>
</a>
<a href="" class="protolink">
<a href="" target="_blank" class="protolink" id="link-ssh">
<div>SSH:</div>
</a>
<a href="" class="protolink">
<a href="" target="_blank" class="protolink" id="link-telnet">
<div>TELNET:</div>
</a>
</div>
@ -71,6 +71,31 @@
$("#checkStates > tbody").empty();
$("#link-http").hide();
$("#link-ssh").hide();
$("#link-telnet").hide();
$.each( node.URIs, function(){
if ((this.Scheme == "http")||(this.Scheme == "https"))
{
$("#link-http")
.attr("href", this.Scheme + "://" + this.Authority + this.Path)
.show();
}
if ((this.Scheme == "ssh"))
{
$("#link-ssh")
.attr("href", this.Scheme + "://" + this.Authority + this.Path)
.show();
}
if ((this.Scheme == "telnet"))
{
$("#link-telnet")
.attr("href", this.Scheme + "://" + this.Authority + this.Path)
.show();
}
});
$.each( node.CheckStates, function(){
var row = $("<tr></tr>")
.append(
@ -95,9 +120,19 @@
var age = (lastTimestamp - currentTimestamp) / 1000;
tdHist.append(
$("<span></span><br>")
$("<div></div><br>")
.addClass("flex row")
.addClass("issue-" + this.NewState )
.text(this.NewState + "[ " + timespan(age) + " ]")
.append($("<span></span>")
.css("flex-grow","1")
.text(this.NewState)
)
.append( $("<span></span>")
.css("flex-grow","0")
.css("width","80px")
.css("text-align","right")
.text(timespan(age))
)
);
lastTimestamp = currentTimestamp;

View File

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

@ -0,0 +1,2 @@


View File

@ -1,35 +1,9 @@
body {
padding: 0px;
margin: 0px;
font-family: Arial, Helvetica, sans-serif;
font-size: 12px;
display: block;
position: absolute;
top: 0px;
bottom: 0px;
left: 0px;
right: 0px;
}
div {
margin: 0px;
padding: 0px;
flex-grow: 0;
}
div#body {
display: flex;
height: 100%;
width: 100%;
flex-direction: column;
}

h1,h2,h3,h4,h5,h6 {
margin: 0px;
padding:2px;
margin-bottom: 8px;
}
h1 > div {
@ -59,19 +33,7 @@ a {
color: inherit;
}
table {
border-collapse: collapse;
}
table > thead {
font-style: italic;
background-color: #A0D0FF;
transition: background-color 1000ms;
}
table > tbody {
}
/*
table td {
vertical-align: top;
@ -98,50 +60,9 @@ table > tbody tr:hover {
color: black;
transition: background-color 250ms;
}
*/
#header {
top: 0px;
left: 0px;
right: 0px;
border-bottom: 1px solid black;
background-color: #c7def5;
padding: 4px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
#header > div {
margin: 4px;
}
#footer {
height: 20px;
padding: 6px;
padding-left: 24px;
background-color: #c7def5;
border-top: 1px solid black;
flex-grow: 0;
flex-shrink: 0;
}
#page {
display: flex;
top: 56px;
bottom: 32px;
left: 0px;
right: 0px;
flex-grow: 1;
flex-direction: row;
}
#nav {
display: flex;
@ -186,7 +107,9 @@ table > tbody tr:hover {
}
.right {
float: right;
/* float: right;
right: 0px;*/
position: absolute;
right: 0px;
}
@ -216,6 +139,10 @@ table > tbody tr:hover {
display: flex;
}
.flex > .grow {
flex-grow: 1;
}
.skylogo {
@ -232,6 +159,10 @@ table > tbody tr:hover {
padding: 4px;
}
.silver {
color: #808080;
}
.indicator {
margin-left: 4px;
margin-right: 4px;
@ -263,7 +194,7 @@ table > tbody tr:hover {
background-color: #00D000;
}
.indicator[state="FAILED"] > div {
background-color: #D00000;
background-color: #C00000;
}
.indicator[state="INITIALIZED"] > div {
background-color: #00D0D0;
@ -421,17 +352,20 @@ fieldset > label {
.issue-OK {
border-color: white;
background-color: inherit;
color: green;
color: #008000;
}
.issue-WARN {
border-color: #C0C000;
/* border-color: #C0C000;
background-color: #C0C000;
color: black;
*/
color: #C0C000;
}
.issue-CRITICAL {
border-color: red;
background-color: red;
color: white;
/* border-color: #C00000;
background-color: #C00000;
color: white;*/
color: #C00000;
}
#CheckState {
@ -444,7 +378,7 @@ fieldset > label {
color: #C0C000;
}
#CheckState.CRITICAL, span#nCRITICAL{
color: RED;
color: #C00000;
margin-right: 12px;
}
@ -468,7 +402,7 @@ fieldset > label {
}
span#nWARN, span#nCRITICAL, span#nOK {
font-size: 24px;
font-size: 16px;
}
.performance-value > div {
@ -503,25 +437,19 @@ span#nWARN, span#nCRITICAL, span#nOK {
}
[bool=false] {
border: 1px solid white;
background-color: red;
background-color: #C00000;
}
.protolink {
position: relative;
display: table-cell;
display: inline-block;
width: 64px;
height: 64px;
border: 3px solid white;
border-radius: 28px;
text-align: center;
vertical-align: middle;
background-color: #009ee3;
color: white;
margin-left: 12px;
margin-right: 12px;
}
.protolink::before {
content: ">";
}
.protolink > div {

View File

@ -4,22 +4,22 @@
<meta charset="utf-8" />
<title>SkyScanner WebUI (Alpha)</title>
<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="/css/jquery-ui.min.css" rel="stylesheet" />
<link href="/css/datatables.min.css" rel="stylesheet" />
<link href="/css/Chart.min.css" rel="stylesheet" />
<link href="/static/css/style.css" rel="stylesheet" />
<link href="/css/style.css" rel="stylesheet" />
<script type="text/javascript" src="/static/skyapi.js"></script>
<script type="text/javascript" src="/static/ln.application.js"></script>
<script type="text/javascript" src="/skyapi.js"></script>
<script type="text/javascript" src="/ln.application.js"></script>
<script type="text/javascript" src="/static/dist/jquery.min.js"></script>
<script type="text/javascript" src="/static/dist/jquery-ui.min.js"></script>
<script type="text/javascript" src="/static/dist/moment-with-locales.js"></script>
<script type="text/javascript" src="/static/dist/moment-timezone-with-data.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>
<script type="text/javascript" src="/dist/jquery.min.js"></script>
<script type="text/javascript" src="/dist/jquery-ui.min.js"></script>
<script type="text/javascript" src="/dist/moment-with-locales.js"></script>
<script type="text/javascript" src="/dist/moment-timezone-with-data.js"></script>
<script type="text/javascript" src="/dist/datatables.min.js"></script>
<script type="text/javascript" src="/dist/percentageBars.js"></script>
<script type="text/javascript" src="/dist/Chart.min.js"></script>
</head>
<body>
<script type="text/javascript">

27
www/ln.tools.js 100644
View File

@ -0,0 +1,27 @@
function ntos(n,l){
n = n.toString();
while (n.length < l){
n = "0" + n;
}
return n;
}
function timespan(value){
var days, hours, minutes, seconds;
value = parseInt(value);
days = parseInt(value / 86400);
value %= 86400;
hours = parseInt(value / 3600);
value %= 3600;
minutes = parseInt(value / 60);
value %= 60;
seconds = parseInt(value);
var r = "";
if (days > 0)
r += `${days}d `;
r += `${ntos(hours,2)}:${ntos(minutes,2)}:${ntos(seconds,2)}`;
return r;
}

View File

@ -11,31 +11,6 @@ function encodeID( t )
return ("" + t).replace( /[\.\/]/g, "_");
}
var lagDetector = null;
function updateState(state)
{
try
{
if (lagDetector)
clearTimeout(lagDetector);
$("#ServerTime").text("ServerTime: " + moment(state.currentTime).format());
lagDetector = setTimeout(function(){
$("#ServerTime")
.empty()
.append(
$("<span style='color: white; background-color: red;'></span>")
.text("Server lag detected")
);
}, 2000);
} catch (e)
{
$("#ServerTime").text("Server state unexpected!");
}
}
/*
function SKYAPI(baseurl){

88
www/topnav.html 100644
View File

@ -0,0 +1,88 @@
<div class="popup">Netz Status
<div>
<div>
<a href="/checks/issues2.html"><div>St&ouml;rf&auml;lle (tabellarisch)</div></a>
</div>
<div>
<a href="/checks/issues.html"><div>St&ouml;rf&auml;lle (detailiert)</div></a>
</div>
</div>
</div>
<div class="popup">Netz Struktur
<div>
<div>
<a href="/network/nodes.html"><div>Knoten</div></a>
</div>
<!-- <div>
<a href="/network/pops.html"><div>PoP Liste</div></a>
</div>
<div>
<a href="/network/l2segments.html"><div>L2 Segmente</div></a>
</div>
<div>
<a href="/network/index.html"><div>PtmP Stationen</div></a>
</div>
<div>
<a href="/network/hoptable.html"><div>Topologie: technisch</div></a>
</div>
<div>
<a href="/network/hoptable.html"><div>Topologie: geographisch</div></a>
</div>
-->
</div>
</div>
<!--
<div class="popup">Crawler
<div>
<div>
<a href="/crawler/status.html"><div>Status</div></a>
</div>
<div>
<a href="/crawler/hosts.html"><div>Hosts</div></a>
</div>
<div>
<a href="/crawler/subnets.html"><div>Subnets</div></a>
</div>
</div>
</div>
<div class="popup">Struktur
<div>
<div>
<a href="/network/index.html"><div>Übersicht</div></a>
</div>
<div>
<a href="/network/hoptable.html"><div>Hop Table</div></a>
</div>
</div>
</div>
<div class="popup">&Uuml;berwachung
<div>
<div>
<a href="/checks/status.html"><div>Status</div></a>
</div>
<div>
<a href="/checks/checks.html"><div>Check Parameter</div></a>
</div>
<div>
<a href="/checks/index.html"><div>Graphen</div></a>
</div>
<div>
<a href="/checks/checkstates.html"><div>Check States</div></a>
</div>
</div>
</div>
-->
<div class="popup">System
<div>
<div>
<a href="/system/index.html"><div>Modul Steuerung</div></a>
</div>
<div>
<a href="/log.html"><div>Logging</div></a>
</div>
</div>
</div>

View File

@ -0,0 +1,101 @@

function graphLoaded(graphDiv, performanceValue, perfData)
{
console.log("graph " + performanceValue.PerfName + " has " + perfData.length + "records.");
var chartColor = performanceValue.CheckState == "CRITICAL" ? '#FF0000' : (performanceValue.CheckState == "WARN") ? '#C0C000' : '#000000';
var htmlChart = $("canvas", graphDiv);
var chart = htmlChart.data("chart");
if (!chart){
chart = new Chart( htmlChart, {
type: 'bar',
data: {
datasets: [
{
label: "-",
data: [],
backgroundColor: chartColor,
}
]
},
options: {
scales: {
yAxes: [
{
ticks: {
callback: ScaleSI,
beginAtZero: true,
}
}
],
xAxes: [{
type: 'time',
time: {
unit: "minute",
tooltipFormat: "DD.MM.YYYY HH:mm",
displayFormats: {
minute: "DD.MM.YYYY HH:mm"
},
parser: moment.unix
}
}]
},
responsive: true,
maintainAspectRatio: false
}
} );
}
chart.data.labels.length = 0;
chart.data.datasets[0].data.length = 0;
chart.data.datasets[0].label = performanceValue.PerfName;
htmlChart.data("chart", chart);
$.each( perfData, function(){
if (this.TimeStamp != 0)
chart.data.datasets[0].data.push( { x: this.TimeStamp, y: this.Value } );
});
graphDiv.prependTo( $("#graphs") );
chart.update();
}
function loadGraph(performanceValue){
var graphName = performanceValue.PerfName;
var perfID = encodeID(graphName);
var graphDiv = $("#graphs").children("#" + perfID);
if (!graphDiv.length){
graphDiv = $("<div style='position: relative; height: 300px; min-width: 400px;'></div>")
.attr("id", perfID)
.data("performanceValue",performanceValue)
.append("<canvas></canvas");
}
LN().rpc("perfValues","GetPerfData",[performanceValue.PerfPath,$("#interval").children("option:selected").val()],function(perfData,e){
if (e){
console.log(e);
} else {
graphLoaded(graphDiv, performanceValue, perfData);
}
});
}
function updateGraphs(){
var timeout = 0;
var gDivs = [];
$("#graphs").children("div").each(function(n,graphDiv){
gDivs.push(graphDiv);
});
gDivs.reverse();
gDivs.forEach(function(graphDiv,i){
var performanceValue = $(graphDiv).data("performanceValue");
setTimeout(function(){
loadGraph(performanceValue);
}, timeout);
timeout += 200;
});
}

View File

@ -0,0 +1,54 @@
<div>
<h1>Aktuelle Störfälle (<span id="lastUpdate">{{ skyscanner.lastIssueUpdate }}</span>)</h1>
<div style="border-bottom: 1px solid black; margin-bottom: 12px;">
<div @click="view.CRITICAL = !view.CRITICAL" style="display: inline-block; width: 120px;" v-bind:class="{ DISABLED: !view.CRITICAL }">Kritisch: <span id="nCRITICAL" class="CRITICAL">{{ skyscanner.issues.CRITICAL }}</span></div>
<div @click="view.WARN = !view.WARN" style="display: inline-block; width: 120px;" v-bind:class="{ DISABLED: !view.WARN }">Warnungen: <span id="nWARN" class="WARN">{{ skyscanner.issues.WARN }}</span></div>
<div @click="view.OK = !view.OK" style="display: inline-block; width: 120px;" v-bind:class="{ DISABLED: !view.OK }">OK &lt; 600s: <span id="nOK" class="OK" v-bind:class="{ DISABLED: !view.OK }">{{ skyscanner.issues.OK }}</span></div>
</div>
<table id="issues" style="width: 100%;">
<thead>
<tr>
<td>Knoten</td>
<td>Anmerkungen</td>
<td>Check</td>
<td>Zeit in aktuellem Status ( / im letzten Status)</td>
<td>Relevante Messwerte</td>
</tr>
</thead>
<tbody>
<tr
v-for="node in CurrentIssues"
:class="'issue-' + node.checkState"
v-if="view[node.checkState]"
>
<td><router-link :to="'/vue/nodes/' + node.ID" target="_blank">{{ node.Name }}</router-link><br>
<span style="color: black;">{{ node.Vendor }} / {{ node.Product }}</span></td>
<td>{{ node.Comment }}</td>
<td>
<span
v-for="checkState in node.CheckStates"
:class="'issue-' + checkState.CheckState"
>{{ checkState.CheckName }}<br></span>
</td>
<td>
<span
v-for="checkState in node.CheckStates"
:class="'issue-' + checkState.CheckState"
>{{ timespan(checkState.currentStateTime) + " " + checkState.previousCheckState }}<br></span>
</td>
<td>
<div
v-for="checkState in node.CheckStates"
v-if="checkState.CheckState != 'OK'"
>
<div
v-for="perfValue in checkState.PerformanceValues"
v-if="perfValue.CheckState != 'OK'"
>{{ perfValue.PerfName }}</div>
</div>
</td>
</tr>
</tbody>
</table>
</div>

View File

@ -0,0 +1,42 @@
var STATES = [ "OK", "WARN", "CRITICAL" ];
SkyScanner.getInitializers().push(
new Promise((resolve,reject)=>{
LN().load("/vue/ln.skyscanner.issues.html").
then((template)=>{
skyScannerRoutes.push(
{
path: "/issues",
label: "Störfälle",
component: {
data: function(){
return {
skyscanner,
view: {
WARN: true,
CRITICAL: true,
OK: true
}
};
},
beforeRouteEnter: function(to,from,next){
skyscanner.updateIssues();
next();
},
beforeRouteLeave: function(from,to,next){
clearTimeout(skyscanner.currentTimeout);
next();
},
computed: {
CurrentIssues: function(){
return this.skyscanner.currentIssues;
},
},
template: template,
},
}
);
resolve();
});
})
);

View File

@ -0,0 +1,220 @@
var SkyScanner = (function(){
var tzOffset = new Date().getTimezoneOffset() * 60;
var defaultOptions = {
};
var initializers = [];
class SkyScanner
{
constructor(options){
this.options = {}
Object.assign(this.options, defaultOptions);
Object.assign(this.options, options);
var self = this;
this.lagDetector = null;
this.currentTimeout = null;
this.serverTime = "N/A";
this.serverString = "N/A";
this.lastIssueUpdate = "N/A";
this.currentIssues = [];
this.currentNodes = [];
this.issues = {
OK: 0,
WARN: 0,
CRITICAL: 0,
};
LN().option("wsError",(e)=>self.wsError(e));
LN().option("wsClose",(e)=>self.wsClose(e));
LN().option("wsUpdate",(e)=>self.wsUpdate(e));
LN().connect();
LN().rpc(null,"GetServerString",[],function(r,e){
self.serverString = r;
});
}
static getInitializers(){
return initializers;
}
wsUpdate(state)
{
try
{
if (this.lagDetector)
clearTimeout(this.lagDetector);
this.serverTime = moment(state.currentTime).format();
this.lagDetector = setTimeout(function(){
this.serverTime = "Server lag detected";
}, 2000);
} catch (e)
{
console.log(e);
}
}
wsError(e){
this.serverTime = "WebSocket: Error: " + JSON.stringify(e);
}
wsClose(e){
this.serverTime = "WebSocket: Connection lost";
setTimeout(function(){
LN().connect();
}, 2500 );
}
updateIssues(){
var self = this;
console.log("Update issue list");
LN().rpc("CheckService","GetIssueList",[],function(r,e){
if (e){
alert("Error fetching current issue list!\n" + JSON.stringify(e));
} else {
self.currentIssues = r;
self.issues = {
OK: 0,
WARN: 0,
CRITICAL: 0,
};
for (var n=0;n<self.currentIssues.length;n++){
var currentNode = self.currentIssues[n];
self.upgradeNode(currentNode);
self.issues[currentNode.checkState]++;
}
self.lastIssueUpdate = moment().format();
}
self.currentTimeout = setTimeout(function(){ self.updateIssues(); }, 10000);
});
}
upgradeNode(currentNode){
currentNode.highestStateTime = 0;
currentNode.checkState = "OK";
$.each(currentNode.CheckStates, function(){
var now = moment.unix((Date.now()/1000) - tzOffset);
var m1 = this.History.length > 0 ? moment.unix(this.History.slice(-1)[0].Timestamp) : moment();
var m2 = this.History.length > 1 ? moment.unix(this.History.slice(-2)[0].Timestamp) : moment();
this.currentStateTime = (now - m1)/1000;
if (STATES.indexOf(currentNode.checkState) < STATES.indexOf(this.CheckState))
{
currentNode.checkState = this.CheckState;
currentNode.highestStateTime = 0;
}
if (currentNode.highestStateTime < this.currentStateTime)
currentNode.highestStateTime = this.currentStateTime;
this.previousCheckState = this.History.length > 1 ? " ( " + this.History.slice(-2)[0].NewState + "=" + timespan((m1 - m2)/1000) + " )" : "";
m1 = now;
$.each(this.History.reverse(), function(){
m2 = moment.unix(this.Timestamp);
this.duration = (m1 - m2)/1000;
m1 = m2;
});
});
}
updateNodes(){
var self = this;
console.log("Update node list");
LN().rpc("entities","GetNodes",[],function(r,e){
if (e){
alert("Error fetching current node list!\n" + JSON.stringify(e));
} else {
self.currentNodes = r;
}
});
}
loadNode(nodeID,cb,refreshIntervall){
var self = this;
LN().rpc("entities","GetNode",[nodeID,],function(r,e){
if (refreshIntervall && self.currentTimeout)
clearTimeout(self.currentTimeout);
skyscanner.upgradeNode(r);
cb(r);
if (refreshIntervall)
setTimeout(()=>{
self.loadNode(nodeID,cb,refreshIntervall);
}, refreshIntervall);
});
}
encodeID( t )
{
return ("" + t).replace( /[\.\/]/g, "_");
}
loadPerformanceGraph(perfPath,interval,cb){
LN().rpc("perfValues","GetPerfData",[perfPath,interval],(perfData,e)=>{
if (e){
console.log(e);
} else {
cb(perfData);
}
});
}
getCheckStateTime(checkState){
var history = []
var now = moment.unix((Date.now()/1000) - tzOffset);
var m1 = checkState.History.length > 0 ? moment.unix(checkState.History.slice(-1)[0].Timestamp) : moment();
var m2 = checkState.History.length > 1 ? moment.unix(checkState.History.slice(-2)[0].Timestamp) : moment();
var currentStateTime = (now - m1)/1000;
timespan(currentStateTime) + (this.History.length > 1 ? " ( " + this.History.slice(-2)[0].NewState + "=" + timespan((m1 - m2)/1000) + " )" : "")
}
static scaleSI(value)
{
if (!value)
return null;
if (value > 1000000000)
return ((value / 1000000000) | 0) + "G";
if (value > 1000000)
return ((value / 1000000) | 0) + "M";
if (value > 1000)
return ((value / 1000) | 0) + "k";
return value;
}
}
return SkyScanner;
})()
var skyScannerRoutes = []

View File

@ -0,0 +1,69 @@
<div>
<div
v-if="!node"
>
<h3>Daten werden geladen...</h3>
</div>
<div
v-if="node"
class="flex row"
>
<div>
<h1>Knoten {{ node.Name }} <span v-if="node.Comment">( {{ node.Comment }} )</span></h1>
<div class="p">
<a
v-for="uri in node.URIs"
:href="uri.Scheme + '://' + uri.Authority + uri.Path"
target="_blank"
class="protolink"
> {{ uri.Scheme.toUpperCase() }} </a>
</div>
<div class="flex column">
<h3>Prüfungen</h3>
<table id="checkStates">
<thead>
<tr>
<td>Check</td>
<td>Zeit in aktuellem Status</td>
<td>Verlauf</td>
<td>Messwerte</td>
</tr>
</thead>
<tbody>
<tr
v-for="checkState in node.CheckStates"
:class="'issue-' + checkState.CheckState"
>
<td>{{ checkState.CheckName }}</td>
<td>{{ timespan(checkState.currentStateTime) }}</td>
<td>
<div
v-for="hstate in checkState.History.slice(0,8)"
class="flex row"
v-bind:class="'issue-'+hstate.NewState"
>
<span class="grow">{{ hstate.NewState }}</span>
<span style="margin-left: 12px;">{{ timespan(hstate.duration) }}</span>
</div>
</td>
<td><div
v-for="perfValue in checkState.PerformanceValues"
:class="'issue-' + perfValue.CheckState"
@click="loadGraph(perfValue)"
>{{ perfValue.PerfName }}
</div>
</td>
</tr>
</tbody>
</table>
<textarea>{{ JSON.stringify( node ) }}</textarea>
</div>
</div>
<div class="flex column grow" id="graphs"></div>
</div>
</div>
</div>

View File

@ -0,0 +1,103 @@
SkyScanner.getInitializers().push(
new Promise((resolve,reject)=>{
LN().load("/vue/ln.skyscanner.node.html").
then((template)=>{
skyScannerRoutes.push(
{
path: "/vue/nodes/:nodeID",
component: {
template: template,
data: function(){ return { node: null }; },
beforeRouteEnter: function(to,from,next){
next((vm)=>{
skyscanner.loadNode(to.params.nodeID,(node)=>{
vm.node = node;
}, 1000);
});
},
beforeRouteLeave: function(from,to,next){
clearTimeout(skyscanner.currentTimeout);
next();
},
},
}
);
resolve();
});
})
);
function loadGraph(perfValue){
skyscanner.loadPerformanceGraph(perfValue.PerfPath,3600,(perfData)=>{
var perfID = skyscanner.encodeID(perfValue.PerfName);
var chartColor = perfValue.CheckState == "CRITICAL" ? '#C00000' : (perfValue.CheckState == "WARN") ? '#C0C000' : '#008000';
var gDiv = $("#" + perfID);
var chart = null;
if (!gDiv.length)
{
gDiv = $("<div></div>").attr("id",perfID).css("height","400px");
var canvas = $("<canvas></canvas>").appendTo(gDiv);
chart = new Chart( canvas, {
type: 'line',
data: {
datasets: [
{
label: "-",
data: [],
borderColor: chartColor,
backgroundColor: null,
fill: false,
}
]
},
options: {
scales: {
yAxes: [
{
ticks: {
callback: SkyScanner.scaleSI,
beginAtZero: true,
}
}
],
xAxes: [{
type: 'time',
time: {
unit: "minute",
tooltipFormat: "DD.MM.YYYY HH:mm",
displayFormats: {
minute: "DD.MM.YYYY HH:mm"
},
parser: moment.unix
}
}]
},
responsive: true,
maintainAspectRatio: false,
cubicInterpolationMode: "monotone",
fill: false,
}
} );
chart.data.labels.length = 0;
chart.data.datasets[0].data.length = 0;
chart.data.datasets[0].label = perfValue.PerfName;
gDiv.data("chart",chart);
} else
{
chart = gDiv.data("chart");
}
chart.data.datasets[0].data.length = 0;
$.each( perfData, function(){
if (this.TimeStamp != 0)
chart.data.datasets[0].data.push( { x: this.TimeStamp, y: this.Value } );
});
chart.update();
$("#graphs").append(gDiv);
});
}

View File

@ -0,0 +1,32 @@
<div>
<h1>Knoten Übersicht</h1>
<table>
<thead>
<tr>
<td>Knoten</td>
<td>Primäre IP</td>
<td>Hersteller</td>
<td>Produkt</td>
<td>Prüfungen</td>
<td>Eindeutige Identität</td>
</tr>
</thead>
<tbody>
<tr
v-for="node in currentNodes"
>
<td>{{ node.Name }}</td>
<td>{{ node.PrimaryIP }}</td>
<td>{{ node.Vendor }}</td>
<td>{{ node.Product }}</td>
<td>
<div
v-for="checkState in node.CheckStates"
>{{ checkState.CheckName }}</div>
</td>
<td>{{ node.UniqueIdentity }}</td>
</tr>
</tbody>
</table>
</div>

View File

@ -0,0 +1,22 @@
SkyScanner.getInitializers().push(
new Promise((resolve,reject)=>{
LN().load("/vue/ln.skyscanner.nodes.html").
then((template)=>{
skyScannerRoutes.push(
{
path: "/nodes",
label: "Knoten",
component: {
template: template,
data: () => skyscanner,
beforeRouteEnter: function(to,from,next){
skyscanner.updateNodes();
next();
},
},
}
);
resolve();
});
})
);

View File

@ -0,0 +1,27 @@
<div>
<h1>System Übersicht / Steuerung</h1>
<h2>Modul Steuerung</h2>
<br>
<div>
<table style="width: 60%;">
<tr>
<td>System</td>
<td></td>
<td style="width: 100px;"></td>
<td style="width: 100px;"><button onclick="LN().rpc('','Shutdown',[],function(r,e){});">Shutdown</button></td>
</tr>
<tr>
<td>Crawler</td>
<td></td>
<td style="width: 100px;"><button onclick="skyapi().call('api/management','StartCrawler')">Start</button></td>
<td style="width: 100px;"><button onclick="skyapi().call('api/management','StopCrawler')">Stop</button></td>
</tr>
<tr>
<td></td>
<td></td>
<td style="width: 100px;"><input type="checkbox" id="cbCrawlHosts"/><label for="cbCrawlHosts">Hosts</label></td>
<td style="width: 100px;"><input type="checkbox" id="cbCrawlSubnets"/><label for="cbCrawlSubnets">Subnets</label></td>
</tr>
</table>
</div>
</div>

View File

@ -0,0 +1,18 @@
SkyScanner.getInitializers().push(
new Promise((resolve,reject)=>{
LN().load("/vue/ln.skyscanner.system.html").
then((template)=>{
skyScannerRoutes.push(
{
path: "/system",
label: "System",
component: {
template: template,
data: function(){ return {}; },
},
}
);
resolve();
});
})
);

View File

@ -0,0 +1,105 @@

html {
padding: 0px;
margin: 0px;
}
body {
padding: 0px;
margin: 0px;
font-family: Arial, Helvetica, sans-serif;
font-size: 12px;
display: block;
position: absolute;
top: 0px;
bottom: 0px;
left: 0px;
right: 0px;
}
div {
margin: 0px;
padding: 0px;
flex-grow: 0;
}
div#body {
display: flex;
height: 100%;
width: 100%;
flex-direction: column;
}
#header {
top: 0px;
left: 0px;
right: 0px;
border-bottom: 1px solid black;
background-color: #c7def5;
padding: 4px;
}
#header > div {
margin: 4px;
}
#navbar {
padding: 8px;
border-bottom: 1px solid black;
font-size: 16px;
color: #808080;
}
#navbar > a {
display: inline-block;
margin-left: 16px;
margin-right: 16px;
}
#navbar > a.router-link-active {
color: black;
}
#page {
padding: 16px;
flex-grow: 1;
overflow-y: scroll;
}
#page::after {
content: '';
display: block;
height: 16px;
width: 100%;
}
#footer {
height: 20px;
padding: 6px;
padding-left: 24px;
background-color: #c7def5;
border-top: 1px solid black;
flex-grow: 0;
flex-shrink: 0;
}
.hidden {
visibility: hidden;
}
.p {
margin-bottom: 12px;
}
.DISABLED {
color: #D0D0D0;
}

View File

@ -0,0 +1,50 @@

table {
border-collapse: collapse;
width: 100%;
}
table tr {
}
table td {
padding: 4px;
border-bottom: 1px solid #D0D0D0;
vertical-align: top;
}
table > thead {
font-style: italic;
background-color: #A0D0FF;
transition: background-color 1000ms;
}
table > thead tr {
}
table > thead td {
}
table > tbody tr {
}
table > tbody td {
}
table > tfoot tr {
}
table > tfoot td {
}
table > tbody > tr:hover > td {
border-top: 2px solid black;
border-bottom: 2px solid black;
}

81
www/vue/vue.html 100644
View File

@ -0,0 +1,81 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>SkyScanner WebUI (Alpha)</title>
<link href="/css/jquery-ui.min.css" rel="stylesheet" />
<link href="/css/datatables.min.css" rel="stylesheet" />
<link href="/css/Chart.min.css" rel="stylesheet" />
<link href="/css/style.css" rel="stylesheet" />
<link href="/vue/page.layout.css" rel="stylesheet" />
<link href="/vue/tables.layout.css" rel="stylesheet" />
<link href="/css/ln.application.css" rel="stylesheet" />
<script type="text/javascript" src="/dist/jquery.min.js"></script>
<script type="text/javascript" src="/dist/jquery-ui.min.js"></script>
<script type="text/javascript" src="/dist/moment-with-locales.js"></script>
<script type="text/javascript" src="/dist/moment-timezone-with-data.js"></script>
<script type="text/javascript" src="/dist/datatables.min.js"></script>
<script type="text/javascript" src="/dist/percentageBars.js"></script>
<script type="text/javascript" src="/dist/Chart.min.js"></script>
<script type="text/javascript" src="/vue.js"></script>
<script type="text/javascript" src="/vue-router.js"></script>
<script type="text/javascript" src="/ln.tools.js"></script>
<script type="text/javascript" src="/ln.application.js"></script>
<script type="text/javascript" src="/vue/ln.skyscanner.js"></script>
<script type="text/javascript" src="/vue/ln.skyscanner.issues.js"></script>
<script type="text/javascript" src="/vue/ln.skyscanner.nodes.js"></script>
<script type="text/javascript" src="/vue/ln.skyscanner.node.js"></script>
<script type="text/javascript" src="/vue/ln.skyscanner.system.js"></script>
</head>
<body>
<div id="body">
<div id="header">
<div class="skylogo">
<div style="background-color: #009ee3; color: white;">Sky</div><div style="background-color: white;">Scanner</div>
</div>
</div>
<div id="navbar">
<router-link
v-for="route in skyScannerRoutes"
v-if="route.label"
v-bind:to="route.path"
>{{ route.label }}</router-link>
</div>
<div id="page">
<router-view></router-view>
</div>
<div id="footer" class="flex row">
<div id="ServerString" class="silver" style="">{{ serverString }}</div>
<div class="grow"></div>
<div id="ServerTime" class="" style="margin-right: 12px;">{{ serverTime }}</div>
</div>
</div>
<script type="text/javascript">
var initializers = SkyScanner.getInitializers();
var skyscanner = new SkyScanner();
Promise.all(initializers)
.then(()=>{
const router = new VueRouter({
routes: skyScannerRoutes,
});
new Vue({
el: "#body",
data: skyscanner,
router,
}).$mount("#body");
});
</script>
</body>
</html>