ln.skyscanner/checks/SkyChecker.cs

211 lines
7.0 KiB
C#
Raw Normal View History

2019-04-04 00:50:53 +02:00
// /**
// * 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;
2019-04-04 19:34:19 +02:00
using ln.snmp;
2019-04-05 00:59:04 +02:00
using ln.http.resources;
2019-04-06 09:36:43 +02:00
using System.Collections.Generic;
2019-08-03 12:57:32 +02:00
2019-04-04 00:50:53 +02:00
namespace ln.skyscanner.checks
{
public class SkyChecker
{
public string BasePath { get; }
2019-04-05 00:59:04 +02:00
[Callable]
2019-04-04 00:50:53 +02:00
public PoolJob[] CurrentJobs => checkPool.CurrentPoolJobs;
2019-04-05 00:59:04 +02:00
[Callable]
2019-04-04 00:50:53 +02:00
public PoolJob[] QueuedJobs => checkPool.QueuedJobs;
2019-04-06 09:36:43 +02:00
2019-04-04 00:50:53 +02:00
2019-04-05 00:59:04 +02:00
[Callable]
2019-04-04 00:50:53 +02:00
public string[] PerfNames => perfFiles.Keys.ToArray();
public bool ContainsPerfFile(String perfName) => perfFiles.ContainsKey(perfName);
2019-04-08 13:06:06 +02:00
[Callable]
2019-04-12 14:19:30 +02:00
public SkyCheckState[] Issues
{
get
{
SkyCheckState[] checkStates = null;
lock (SkyScanner.Instance.Entities.SkyCheckStates)
{
2019-04-15 09:18:41 +02:00
checkStates = Timing.Meassure("scheduler: checkStates", () => SkyScanner.Instance.Entities.SkyCheckStates.ToArray());
2019-04-12 14:19:30 +02:00
}
return checkStates.Where((cs) => (!String.Empty.Equals(cs.Node?.Vendor) && ((cs.CheckState != CheckState.OK) || ((cs.UnchangedTime < TimeSpan.FromMinutes(10)) && (cs.History.Length > 1) )))).ToArray();
2019-04-12 14:19:30 +02:00
}
}
2019-04-08 13:06:06 +02:00
2019-07-11 10:17:27 +02:00
[Callable]
public SkyCheckState[] CheckStatesByHostID(Guid nodeID)
{
lock (SkyScanner.Instance.Entities.SkyCheckStates)
{
return SkyScanner.Instance.Entities.SkyCheckStates.Query("Node", nodeID).ToArray();
}
}
2019-04-04 19:34:19 +02:00
public SNMPEngine SNMPEngine { get; }
2019-04-04 00:50:53 +02:00
BTree<string, PerfFile> perfFiles = new BTree<string, PerfFile>();
Pool checkPool = new Pool(0);
Thread threadScheduler;
bool stopping;
2019-04-06 09:36:43 +02:00
List<SkyCheckState> saveQueue = new List<SkyCheckState>();
2019-04-05 00:59:04 +02:00
2019-04-04 00:50:53 +02:00
public SkyChecker()
{
BasePath = Path.Combine(SkyScanner.Instance.BasePath, "perfdb");
2019-04-05 00:59:04 +02:00
2019-04-11 08:30:13 +02:00
Logging.Log(LogLevel.INFO, "SkyChecker: created");
2019-04-04 19:34:19 +02:00
SNMPEngine = new SNMPEngine();
2019-04-05 00:59:04 +02:00
SNMPEngine.Timeout = 4000;
2019-04-04 00:50:53 +02:00
}
public void Start()
{
if ((threadScheduler != null) && (threadScheduler.IsAlive))
throw new NotSupportedException("SkyChecker.scheduler() already running");
2019-08-03 12:57:32 +02:00
checkPool.SetPoolSize(256);
2019-04-06 09:36:43 +02:00
Thread.Sleep(2500);
2019-04-04 00:50:53 +02:00
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();
}
2019-04-12 00:52:55 +02:00
public PerfFile GetPerfFile(params string[] perfPath)
2019-04-04 00:50:53 +02:00
{
lock (this)
{
2019-04-12 00:52:55 +02:00
string perfName = string.Join("/", perfPath);
2019-04-04 00:50:53 +02:00
if (!perfFiles.ContainsKey(perfName))
{
2019-04-12 00:52:55 +02:00
String perfDirectory = Path.Combine(BasePath, Path.Combine(perfPath.Take(perfPath.Length - 1).ToArray()));
2019-04-04 00:50:53 +02:00
if (!Directory.Exists(perfDirectory))
Directory.CreateDirectory(perfDirectory);
2019-04-12 00:52:55 +02:00
String perfFileName = Path.Combine(perfDirectory, String.Format("{0}.perf", perfPath[perfPath.Length-1]));
2019-04-04 00:50:53 +02:00
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];
}
}
2019-04-12 00:52:55 +02:00
2019-04-04 00:50:53 +02:00
private void scheduler()
{
long nextMinute = DateTimeOffset.Now.ToUnixTimeMilliseconds();
try
{
while (!stopping)
{
2019-04-06 09:36:43 +02:00
List<CheckJob> checkJobs = new List<CheckJob>();
Logging.Log(LogLevel.INFO, "SkyChecker.scheduler(): scheduler save CheckStates");
lock (saveQueue)
{
foreach (SkyCheckState checkState in saveQueue)
{
2019-04-11 08:30:13 +02:00
SkyScanner.Instance.Entities.SkyCheckStates.Upsert(checkState);
2019-04-06 09:36:43 +02:00
}
saveQueue.Clear();
}
Logging.Log(LogLevel.INFO, "SkyChecker.scheduler(): scheduler starts");
2019-04-11 08:30:13 +02:00
foreach (Node node in SkyScanner.Instance.Entities.NodeCollection)
2019-04-04 00:50:53 +02:00
{
CheckJob checkJob = new CheckJob(node);
2019-04-06 09:36:43 +02:00
checkJobs.Add(checkJob);
2019-04-04 00:50:53 +02:00
}
2019-04-06 09:36:43 +02:00
Logging.Log(LogLevel.INFO, "SkyChecker.scheduler(): prepared {0} checks", checkJobs.Count);
Logging.Log(LogLevel.INFO, "SkyChecker.scheduler(): scheduled {0} checks", checkPool.Enqueue(checkJobs));
2019-04-04 00:50:53 +02:00
while ((nextMinute - DateTimeOffset.Now.ToUnixTimeMilliseconds()) < 0)
nextMinute += 60000;
Thread.Sleep((int)(nextMinute - DateTimeOffset.Now.ToUnixTimeMilliseconds()));
}
} catch (ThreadInterruptedException)
{
2019-04-05 00:59:04 +02:00
} catch (OperationCanceledException)
{
2019-04-04 00:50:53 +02:00
}
}
2019-04-06 09:36:43 +02:00
public void Save(SkyCheckState checkState)
{
lock (saveQueue)
{
saveQueue.Add(checkState);
}
}
2019-04-04 00:50:53 +02:00
public ComponentState State
{
get
{
return ComponentState.INITIALIZED;
}
}
}
}