2011-10-07 06:36:04 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
using System.Runtime.Remoting;
|
|
|
|
|
using System.Timers;
|
2011-11-13 04:22:13 +00:00
|
|
|
|
using Exceptioneer.WindowsFormsClient;
|
2011-10-07 06:36:04 +00:00
|
|
|
|
using NLog;
|
|
|
|
|
using Ninject;
|
2011-10-23 05:26:43 +00:00
|
|
|
|
using NzbDrone.Common;
|
2012-01-13 22:15:40 +00:00
|
|
|
|
using NzbDrone.Common.Model;
|
2011-10-07 06:36:04 +00:00
|
|
|
|
|
|
|
|
|
namespace NzbDrone.Providers
|
|
|
|
|
{
|
|
|
|
|
public class MonitoringProvider
|
|
|
|
|
{
|
2011-10-07 06:43:35 +00:00
|
|
|
|
private static readonly Logger Logger = LogManager.GetLogger("Host.MonitoringProvider");
|
2011-10-07 06:36:04 +00:00
|
|
|
|
|
|
|
|
|
private readonly IISProvider _iisProvider;
|
|
|
|
|
private readonly ProcessProvider _processProvider;
|
2011-10-07 06:57:43 +00:00
|
|
|
|
private readonly WebClientProvider _webClientProvider;
|
2012-01-13 22:15:40 +00:00
|
|
|
|
private readonly ConfigFileProvider _configFileProvider;
|
2011-10-07 06:36:04 +00:00
|
|
|
|
|
|
|
|
|
private int _pingFailCounter;
|
|
|
|
|
private Timer _pingTimer;
|
|
|
|
|
|
|
|
|
|
[Inject]
|
2011-10-07 06:57:43 +00:00
|
|
|
|
public MonitoringProvider(ProcessProvider processProvider, IISProvider iisProvider,
|
2012-01-13 22:15:40 +00:00
|
|
|
|
WebClientProvider webClientProvider, ConfigFileProvider configFileProvider)
|
2011-10-07 06:36:04 +00:00
|
|
|
|
{
|
|
|
|
|
_processProvider = processProvider;
|
|
|
|
|
_iisProvider = iisProvider;
|
2011-10-07 06:57:43 +00:00
|
|
|
|
_webClientProvider = webClientProvider;
|
2012-01-13 22:15:40 +00:00
|
|
|
|
_configFileProvider = configFileProvider;
|
2011-10-07 06:57:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public MonitoringProvider()
|
|
|
|
|
{
|
2011-10-07 06:36:04 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Start()
|
|
|
|
|
{
|
2011-10-17 01:42:20 +00:00
|
|
|
|
AppDomain.CurrentDomain.UnhandledException += ((s, e) => AppDomainException(e.ExceptionObject as Exception));
|
2011-10-07 06:36:04 +00:00
|
|
|
|
|
|
|
|
|
AppDomain.CurrentDomain.ProcessExit += ProgramExited;
|
|
|
|
|
AppDomain.CurrentDomain.DomainUnload += ProgramExited;
|
|
|
|
|
|
|
|
|
|
var prioCheckTimer = new Timer(5000);
|
|
|
|
|
prioCheckTimer.Elapsed += EnsurePriority;
|
|
|
|
|
prioCheckTimer.Enabled = true;
|
|
|
|
|
|
2012-01-23 02:24:16 +00:00
|
|
|
|
_pingTimer = new Timer(120000) { AutoReset = true };
|
2011-10-07 06:36:04 +00:00
|
|
|
|
_pingTimer.Elapsed += (PingServer);
|
|
|
|
|
_pingTimer.Start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public virtual void EnsurePriority(object sender, ElapsedEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
var currentProcess = _processProvider.GetCurrentProcess();
|
|
|
|
|
if (currentProcess.Priority != ProcessPriorityClass.Normal)
|
|
|
|
|
{
|
|
|
|
|
_processProvider.SetPriority(currentProcess.Id, ProcessPriorityClass.Normal);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var iisProcess = _processProvider.GetProcessById(_iisProvider.IISProcessId);
|
|
|
|
|
if (iisProcess != null && iisProcess.Priority != ProcessPriorityClass.Normal &&
|
|
|
|
|
iisProcess.Priority != ProcessPriorityClass.AboveNormal)
|
|
|
|
|
{
|
|
|
|
|
_processProvider.SetPriority(iisProcess.Id, ProcessPriorityClass.Normal);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public virtual void PingServer(object sender, ElapsedEventArgs e)
|
|
|
|
|
{
|
2012-01-13 22:15:40 +00:00
|
|
|
|
if (!_iisProvider.ServerStarted || _configFileProvider.AuthenticationType == AuthenticationType.Windows) return;
|
2011-10-07 06:36:04 +00:00
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
2011-10-07 06:57:43 +00:00
|
|
|
|
string response = _webClientProvider.DownloadString(_iisProvider.AppUrl + "/health");
|
2011-10-07 06:36:04 +00:00
|
|
|
|
|
|
|
|
|
if (!response.Contains("OK"))
|
|
|
|
|
{
|
|
|
|
|
throw new ServerException("Health services responded with an invalid response.");
|
|
|
|
|
}
|
2011-10-07 06:57:43 +00:00
|
|
|
|
|
2011-10-07 06:36:04 +00:00
|
|
|
|
if (_pingFailCounter > 0)
|
|
|
|
|
{
|
|
|
|
|
Logger.Info("Application pool has been successfully recovered.");
|
|
|
|
|
}
|
2011-10-07 06:57:43 +00:00
|
|
|
|
|
2011-10-07 06:36:04 +00:00
|
|
|
|
_pingFailCounter = 0;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_pingFailCounter++;
|
|
|
|
|
Logger.ErrorException("Application pool is not responding. Count " + _pingFailCounter, ex);
|
|
|
|
|
if (_pingFailCounter > 2)
|
|
|
|
|
{
|
|
|
|
|
_iisProvider.RestartServer();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ProgramExited(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
_iisProvider.StopServer();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2011-10-17 01:42:20 +00:00
|
|
|
|
public static void AppDomainException(Exception excepion)
|
2011-10-07 06:36:04 +00:00
|
|
|
|
{
|
2011-10-15 00:59:24 +00:00
|
|
|
|
Console.WriteLine("EPIC FAIL: {0}", excepion);
|
2011-10-07 06:36:04 +00:00
|
|
|
|
|
2011-11-13 04:22:13 +00:00
|
|
|
|
if (EnviromentProvider.IsProduction)
|
2011-10-07 06:36:04 +00:00
|
|
|
|
{
|
2011-11-13 04:22:13 +00:00
|
|
|
|
new Client
|
|
|
|
|
{
|
|
|
|
|
ApiKey = "43BBF60A-EB2A-4C1C-B09E-422ADF637265",
|
|
|
|
|
ApplicationName = "NzbDrone",
|
|
|
|
|
CurrentException = excepion as Exception
|
|
|
|
|
}.Submit();
|
|
|
|
|
}
|
2011-10-17 01:42:20 +00:00
|
|
|
|
|
2011-11-14 03:37:36 +00:00
|
|
|
|
Logger.FatalException("EPIC FAIL: " + excepion.Message, excepion);
|
2011-10-07 06:36:04 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|