private MonitoringBackgroundWorker(IHubConnectionContext<dynamic> clients) { Clients = clients; _statsToStore = new DataTable(); _statsToStore.Columns.Add("ServerFriendlyName", typeof(string)); _statsToStore.Columns.Add("CounterFriendlyName", typeof(string)); _statsToStore.Columns.Add("CounterValue", typeof(double)); _statsToStore.Columns.Add("CounterValueDate", typeof(DateTime)); SandboxDatabaseManagerServiceClient client; MyMonitoredServers = new List<MonitoredServer>(); foreach (var serverToMonitor in MonitoredServers.Instance.ItemsList) { try { client = new SandboxDatabaseManagerServiceClient("NetTcpBinding_ISandboxDatabaseManagerService", serverToMonitor.RemoteAddress); MyMonitoredServers.Add(new MonitoredServer() { Name = serverToMonitor.FriendlyName, Client = client, IsOk = true }); } catch (Exception ex) { Log.Error(String.Format("Failed to construct SandboxDatabaseManagerServiceClient for client FriendlyName: {0}, RemotAddress: {1}", serverToMonitor.FriendlyName, serverToMonitor.RemoteAddress), ex); } } backgroundTask = new Task(MonitorAndPushStatistics, TaskCreationOptions.LongRunning); backgroundTask.Start(); }
private async void MonitorAndPushStatistics() { object sync = new object(); List<ServerPerformanceCounterStats> stats; while (true) { stats = new List<ServerPerformanceCounterStats>(); Parallel.ForEach(MyMonitoredServers.Where(x => x.IsOk), (serverClinent, LoopState) => { try { var result = serverClinent.Client.GetPerformanceCounterResult(); lock (sync) { stats.Add(new ServerPerformanceCounterStats(serverClinent.Name, result)); } } catch (Exception ex) { Log.Error(String.Format("Exception retrieving statistics from remote server name {0}.", serverClinent.Name), ex); serverClinent.IsOk = false; } }); // try to reconstruct clients for monitoring servers SandboxDatabaseManagerServiceClient client; string remoteAddress = ""; foreach (var friendlyFailedServers in MyMonitoredServers.Where(x => !x.IsOk)) { try { Log.InfoFormat("Trying to re-establish connection with monitored server: {0}", friendlyFailedServers.Name); remoteAddress = MonitoredServers.Instance.GetRemoteAddress(friendlyFailedServers.Name); client = new SandboxDatabaseManagerServiceClient("NetTcpBinding_ISandboxDatabaseManagerService", remoteAddress); friendlyFailedServers.Client = client; friendlyFailedServers.IsOk = true; } catch (Exception ex) { Log.Error(String.Format("Failed to re-construct SandboxDatabaseManagerServiceClient for client FriendlyName: {0}, RemotAddress: {1}", friendlyFailedServers.Name, remoteAddress), ex); } } CurrentStats = stats; try { Clients.All.updatePerformanceCounterStats(CurrentStats); } catch (Exception ex) { Log.Error("Exception while updating stats to clients.", ex); } _section.EnterWriteLock(); try { foreach (var serverStats in stats) { foreach (var counter in serverStats.ListOfCounterValues) { _statsToStore.Rows.Add(serverStats.ServerName, counter.CounterFriendlyName, counter.CounteValue, serverStats.StatsTime); } } } finally { _section.ExitWriteLock(); } if ((DateTime.Now - _lastRemoveOldCounterDataEach) > _removeOldCounterDataEach) { _lastRemoveOldCounterDataEach = DateTime.Now; Task.Run(async () => { try { await Task.Delay(10000); Database.DatabaseContext.RemoveOldDataFromDB(); _section.EnterWriteLock(); try { _countersDataMinDates = Database.DatabaseContext.GetCountersDataMinDates(); } finally { _section.ExitWriteLock(); } } catch (Exception ex) { Log.Error(ex); } }); } if ((DateTime.Now - _lastMaxStored) > _storeCounterDataEach) { DataTable dtResults = new DataTable(); _section.EnterReadLock(); try { DataView dv = new DataView(_statsToStore); dv.RowFilter = "CounterValueDate > '" + _lastMaxStored.ToString("o") + "'"; dtResults = dv.ToTable(); } finally { _section.ExitReadLock(); } if (dtResults.Rows.Count > 0) { _lastMaxStored = (DateTime)dtResults.Compute("MAX(CounterValueDate)", null); Task.Run(() => { try { Database.DatabaseContext.StoreCountersData(dtResults); } catch (Exception ex) { Log.Error(ex); } }); _section.EnterWriteLock(); try { string removeOlderThan = _lastMaxStored.AddHours(-1).ToString("s"); foreach (var row in _statsToStore.Select("CounterValueDate <= '" + removeOlderThan + "'")) { _statsToStore.Rows.Remove(row); } }finally { _section.ExitWriteLock(); } } } await Task.Delay(10000); } }