204 lines
6.7 KiB
C#
204 lines
6.7 KiB
C#
// /**
|
|
// * 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;
|
|
using ln.snmp;
|
|
using ln.http.resources;
|
|
using ln.types.odb;
|
|
using System.Collections.Generic;
|
|
using ln.types.odb.mapped;
|
|
using System.Runtime.CompilerServices;
|
|
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);
|
|
|
|
[Callable]
|
|
public SkyCheckState[] Issues
|
|
{
|
|
get
|
|
{
|
|
SkyCheckState[] checkStates = null;
|
|
lock (SkyScanner.Instance.Entities.SkyCheckStates)
|
|
{
|
|
checkStates = Timing.Meassure("scheduler: checkStates", () => SkyScanner.Instance.Entities.SkyCheckStates.ToArray());
|
|
}
|
|
return checkStates.Where((cs) => (!String.Empty.Equals(cs.Node?.Vendor) && (cs.CheckState != CheckState.OK))).ToArray();
|
|
}
|
|
}
|
|
|
|
public SNMPEngine SNMPEngine { get; }
|
|
|
|
BTree<string, PerfFile> perfFiles = new BTree<string, PerfFile>();
|
|
|
|
Pool checkPool = new Pool(0);
|
|
Thread threadScheduler;
|
|
|
|
bool stopping;
|
|
|
|
List<SkyCheckState> saveQueue = new List<SkyCheckState>();
|
|
|
|
public SkyChecker()
|
|
{
|
|
BasePath = Path.Combine(SkyScanner.Instance.BasePath, "perfdb");
|
|
|
|
Logging.Log(LogLevel.INFO, "SkyChecker: created");
|
|
|
|
SNMPEngine = new SNMPEngine();
|
|
SNMPEngine.Timeout = 4000;
|
|
}
|
|
|
|
public void Start()
|
|
{
|
|
if ((threadScheduler != null) && (threadScheduler.IsAlive))
|
|
throw new NotSupportedException("SkyChecker.scheduler() already running");
|
|
|
|
checkPool.SetPoolSize(256);
|
|
|
|
Thread.Sleep(2500);
|
|
|
|
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 PerfFile GetPerfFile(params string[] perfPath)
|
|
{
|
|
lock (this)
|
|
{
|
|
string perfName = string.Join("/", perfPath);
|
|
if (!perfFiles.ContainsKey(perfName))
|
|
{
|
|
String perfDirectory = Path.Combine(BasePath, Path.Combine(perfPath.Take(perfPath.Length - 1).ToArray()));
|
|
if (!Directory.Exists(perfDirectory))
|
|
Directory.CreateDirectory(perfDirectory);
|
|
|
|
String perfFileName = Path.Combine(perfDirectory, String.Format("{0}.perf", perfPath[perfPath.Length-1]));
|
|
|
|
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)
|
|
{
|
|
List<CheckJob> checkJobs = new List<CheckJob>();
|
|
|
|
Logging.Log(LogLevel.INFO, "SkyChecker.scheduler(): scheduler save CheckStates");
|
|
|
|
lock (saveQueue)
|
|
{
|
|
foreach (SkyCheckState checkState in saveQueue)
|
|
{
|
|
SkyScanner.Instance.Entities.SkyCheckStates.Upsert(checkState);
|
|
}
|
|
saveQueue.Clear();
|
|
}
|
|
|
|
Logging.Log(LogLevel.INFO, "SkyChecker.scheduler(): scheduler starts");
|
|
|
|
foreach (Node node in SkyScanner.Instance.Entities.NodeCollection)
|
|
{
|
|
CheckJob checkJob = new CheckJob(node);
|
|
checkJobs.Add(checkJob);
|
|
}
|
|
Logging.Log(LogLevel.INFO, "SkyChecker.scheduler(): prepared {0} checks", checkJobs.Count);
|
|
Logging.Log(LogLevel.INFO, "SkyChecker.scheduler(): scheduled {0} checks", checkPool.Enqueue(checkJobs));
|
|
|
|
while ((nextMinute - DateTimeOffset.Now.ToUnixTimeMilliseconds()) < 0)
|
|
nextMinute += 60000;
|
|
|
|
Thread.Sleep((int)(nextMinute - DateTimeOffset.Now.ToUnixTimeMilliseconds()));
|
|
}
|
|
} catch (ThreadInterruptedException)
|
|
{
|
|
} catch (OperationCanceledException)
|
|
{
|
|
}
|
|
|
|
}
|
|
|
|
public void Save(SkyCheckState checkState)
|
|
{
|
|
lock (saveQueue)
|
|
{
|
|
saveQueue.Add(checkState);
|
|
}
|
|
}
|
|
|
|
|
|
public ComponentState State
|
|
{
|
|
get
|
|
{
|
|
return ComponentState.INITIALIZED;
|
|
}
|
|
}
|
|
}
|
|
}
|