master
exsersewo 5 years ago
parent cf58106440
commit d811761ccc
  1. 25
      Cachet-Monitor.sln
  2. 23
      Cachet-Monitor/Cachet-Monitor.csproj
  3. 62
      Cachet-Monitor/Models/Configuration/Configuration.cs
  4. 24
      Cachet-Monitor/Models/Configuration/Monitor/Monitor.cs
  5. 15
      Cachet-Monitor/Models/Configuration/Monitor/MonitorSettings.cs
  6. 11
      Cachet-Monitor/Models/Configuration/Monitor/MonitorType.cs
  7. 223
      Cachet-Monitor/Program.cs

@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29728.190
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Cachet-Monitor", "Cachet-Monitor\Cachet-Monitor.csproj", "{95DC5C5F-1837-4577-BD25-CA8BE900060D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{95DC5C5F-1837-4577-BD25-CA8BE900060D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{95DC5C5F-1837-4577-BD25-CA8BE900060D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{95DC5C5F-1837-4577-BD25-CA8BE900060D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{95DC5C5F-1837-4577-BD25-CA8BE900060D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {564B86A6-C853-4278-B04A-BF3776B746B0}
EndGlobalSection
EndGlobal

@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<RootNamespace>Cachet_Monitor</RootNamespace>
<AssemblyVersion>2020.2.24.0</AssemblyVersion>
<FileVersion>2020.2.24.0</FileVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CachNet" Version="0.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="RestEase" Version="1.4.10" />
</ItemGroup>
<ItemGroup>
<Reference Include="CachNet">
<HintPath>..\CachNet.dll</HintPath>
</Reference>
</ItemGroup>
</Project>

@ -0,0 +1,62 @@
using Cachet_Monitor.Models.Config;
using System;
using System.Collections.Generic;
namespace Cachet_Monitor.Models
{
public class Configuration
{
public Uri ApiBase { get; set; }
public string ApiKey { get; set; }
public List<Monitor> Monitors { get; set; }
public static Configuration Default = new Configuration
{
ApiBase = new Uri("https://domain.example.com"),
ApiKey = "AAABBBCCC11223344556",
Monitors = new List<Monitor>
{
new Monitor
{
Name = "Website",
Target = "https://example.com",
ComponentId = 1,
MetricId = 1,
Interval = 60,
Timeout = 5,
Type = MonitorType.HTTP,
Settings = new MonitorSettings
{
ExpectedStatusCode = 200,
Method = "GET"
}
},
new Monitor
{
Name = "Database",
Target = "example.com",
ComponentId = 1,
MetricId = 1,
Interval = 60,
Timeout = 5,
Type = MonitorType.PORT,
Settings = new MonitorSettings
{
Port = 3306
}
},
new Monitor
{
Name = "Server",
Target = "example.com",
ComponentId = 1,
MetricId = 1,
Interval = 60,
Timeout = 5,
Type = MonitorType.ICMP
}
}
};
}
}

@ -0,0 +1,24 @@
namespace Cachet_Monitor.Models.Config
{
public class Monitor
{
//Meta
public string Name;
public string Target;
//Cachet
public int ComponentId;
public int MetricId;
//Timing
public int Interval;
public int Timeout;
public MonitorType Type;
public MonitorSettings Settings;
}
}

@ -0,0 +1,15 @@
namespace Cachet_Monitor.Models.Config
{
public class MonitorSettings
{
//Http
public string Method = "GET";
public int ExpectedStatusCode = 200;
//TCP
public int Port;
public int TTL;
}
}

@ -0,0 +1,11 @@
using System;
namespace Cachet_Monitor.Models.Config
{
public enum MonitorType
{
HTTP,
PORT,
ICMP
}
}

@ -0,0 +1,223 @@
using Cachet_Monitor.Models;
using Cachet_Monitor.Models.Config;
using Monitor = Cachet_Monitor.Models.Config.Monitor;
using CachNet;
using Newtonsoft.Json;
using System;
using System.IO;
using System.Threading.Tasks;
using System.Threading;
using System.Net.Sockets;
using System.Net;
using System.Diagnostics;
using CachNet.Entities;
using System.Net.NetworkInformation;
namespace Cachet_Monitor
{
internal class Program
{
private static Configuration Configuration;
private static CachetClient Cachet;
private static void Main()
{
{
var config = Path.Combine(Environment.CurrentDirectory, "settings.json");
if (File.Exists(config))
{
Configuration = JsonConvert.DeserializeObject<Configuration>(File.ReadAllText(config));
}
else
{
File.WriteAllText(config, JsonConvert.SerializeObject(Configuration.Default, Formatting.Indented));
Console.WriteLine($"Written a new instance of the configuration to: {config}");
Console.ReadKey();
Environment.Exit(0);
}
}
Cachet = new CachetClient(Configuration.ApiBase.OriginalString, Configuration.ApiKey);
MainAsync().GetAwaiter().GetResult();
}
private static async Task MainAsync()
{
foreach (var monitor in Configuration.Monitors)
{
new Thread(async () =>
{
Thread.CurrentThread.IsBackground = true;
while (true)
{
await DoMonitorCheck(Cachet, monitor).ConfigureAwait(false);
await Task.Delay(monitor.Interval * 1000);
}
}).Start();
}
await Task.Delay(-1).ConfigureAwait(false);
}
private static async Task DoMonitorCheck(CachetClient Cachet, Monitor monitor)
{
ComponentStatus componentStatus = 0;
switch (monitor.Type)
{
case MonitorType.PORT:
{
using (TcpClient tcpClient = new TcpClient())
{
try
{
tcpClient.Connect(monitor.Target, monitor.Settings.Port);
await Cachet.UpdateComponentAsync(monitor.ComponentId, new PutComponent
{
Status = ComponentStatus.Operational,
});
}
catch (Exception)
{
await Cachet.UpdateComponentAsync(monitor.ComponentId, new PutComponent
{
Status = ComponentStatus.MajorOutage,
});
}
}
}
break;
case MonitorType.ICMP:
{
Ping ping = new Ping();
PingOptions options = new PingOptions
{
DontFragment = true,
Ttl = monitor.Settings.TTL
};
PingReply reply = ping.Send(monitor.Target, monitor.Timeout, null, options);
await Cachet.AddMetricPointAsync(monitor.MetricId, new PostMetricPoint
{
Value = (int)reply.RoundtripTime
});
if (reply.Status == IPStatus.Success)
{
await Cachet.UpdateComponentAsync(monitor.ComponentId, new PutComponent
{
Status = ComponentStatus.Operational,
});
}
if (reply.RoundtripTime >= monitor.Timeout)
{
await Cachet.UpdateComponentAsync(monitor.ComponentId, new PutComponent
{
Status = ComponentStatus.PerformanceIssues,
});
}
if (reply.Status != IPStatus.Success)
{
if (reply.Status == IPStatus.TimedOut)
{
await Cachet.UpdateComponentAsync(monitor.ComponentId, new PutComponent
{
Status = ComponentStatus.PartialOutage,
});
}
else
{
await Cachet.UpdateComponentAsync(monitor.ComponentId, new PutComponent
{
Status = ComponentStatus.MajorOutage,
});
}
}
}
break;
case MonitorType.HTTP:
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(monitor.Target);
request.Timeout = monitor.Timeout * 1000;
Stopwatch timer = new Stopwatch();
timer.Start();
try
{
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
timer.Stop();
if (response.StatusCode == (HttpStatusCode)monitor.Settings.ExpectedStatusCode)
{
var x = await Cachet.UpdateComponentAsync(monitor.ComponentId, new PutComponent
{
Status = ComponentStatus.Operational,
});
}
else
{
await Cachet.UpdateComponentAsync(monitor.ComponentId, new PutComponent
{
Status = ComponentStatus.PartialOutage,
});
}
response.Close();
}
catch (WebException ex)
{
timer.Stop();
if (ex.Status == WebExceptionStatus.ProtocolError)
{
if (ex.Response is HttpWebResponse response)
{
if (response.StatusCode == (HttpStatusCode)monitor.Settings.ExpectedStatusCode)
{
await Cachet.UpdateComponentAsync(monitor.ComponentId, new PutComponent
{
Status = ComponentStatus.Operational,
});
}
}
}
else
{
if (ex.Status == WebExceptionStatus.Timeout)
{
await Cachet.UpdateComponentAsync(monitor.ComponentId, new PutComponent
{
Status = ComponentStatus.PerformanceIssues,
});
}
else
{
await Cachet.UpdateComponentAsync(monitor.ComponentId, new PutComponent
{
Status = ComponentStatus.MajorOutage,
});
}
}
}
await Cachet.AddMetricPointAsync(monitor.MetricId, new PostMetricPoint
{
Value = (int)timer.ElapsedMilliseconds
});
}
break;
}
Console.WriteLine($"Ran check on \"{monitor.Target}\" Status: {componentStatus}");
}
}
}
Loading…
Cancel
Save