ln.skyscanner/checks/SkyChecker.cs

189 lines
6.1 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;
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);
public SNMPEngine SNMPEngine { get; }
BTree<string, PerfFile> perfFiles = new BTree<string, PerfFile>();
Pool checkPool = new Pool(0);
Thread threadScheduler;
bool stopping;
ODB odb;
public ODBCollection<SkyCheckState> CheckStates { get; private set; }
public SkyChecker()
{
BasePath = Path.Combine(SkyScanner.Instance.BasePath, "perfdb");
SNMPEngine = new SNMPEngine();
SNMPEngine.Timeout = 4000;
odb = new ODB(Path.Combine(BasePath));
CheckStates = odb.GetCollection<SkyCheckState>();
CheckStates.EnsureIndex("CheckName");
CheckStates.EnsureIndex("UniqueNodeIdentifier");
}
public void Start()
{
if ((threadScheduler != null) && (threadScheduler.IsAlive))
throw new NotSupportedException("SkyChecker.scheduler() already running");
checkPool.SetPoolSize(128);
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)
{
} catch (OperationCanceledException)
{
}
}
public ComponentState State
{
get
{
return ComponentState.INITIALIZED;
}
}
}
}