/// <summary> /// CleanupOperations constructor. /// </summary> /// <param name="telemetry">Reference to the WatchdogService ReportMetrics instance.</param> /// <param name="interval">Timer interval.</param> /// <param name="token">CancellationToken instance.</param> /// <param name="timeout">Default fabric operation timeout value.</param> public CleanupOperations(IWatchdogTelemetry telemetry, TimeSpan interval, CancellationToken token, TimeSpan timeout = default(TimeSpan)) { ServiceEventSource.Current.Trace("CleanupOperations called"); this._token = token; this._timeout = (default(TimeSpan) == timeout) ? TimeSpan.FromSeconds(5) : timeout; this._telemetry = telemetry ?? throw new ArgumentNullException("Argument is null.", nameof(telemetry)); // Create a timer that calls the local method. this._cleanupTimer = new Timer( async(o) => { try { await this.CleanupDiagnosticTablesAsync(); } catch (Exception ex) { ServiceEventSource.Current.Exception($"Last chance exception: {ex.Message}", ex.GetType().Name, ex.StackTrace); } }, this._token, interval, interval.Add(TimeSpan.FromSeconds(30))); }
/// <summary> /// Services that want to implement a processing loop which runs /// when it is primary and has write status, just override this method with their logic /// </summary> /// <param name="cancellationToken">Cancellation token to monitor for cancellation requests.</param> /// <returns>A Task that represents outstanding operation.</returns> protected override async Task RunAsync(CancellationToken cancellationToken) { ServiceEventSource.Current.ServiceMessage(this.Context, "RunAsync called"); ServiceEventSource.Current.Trace($"RunAsync INFO: RunnAsync called.."); // Check if settings are null. If they are, throw. if (null == this.Settings) { ServiceEventSource.Current.Trace($"RunAsync ERROR: settings are null..."); throw new ArgumentNullException("Settings are null, check Config/Settings exist."); } // Create the operations classes. ServiceEventSource.Current.Trace($"RunAsync INFO: creating the telemetry class"); this._telemetry = new AiTelemetry(this.GetConfigValueAsString(WatchdogConfigSectionName, "AIKey")); ServiceEventSource.Current.Trace($"RunAsync INFO: creating the metrics class"); this._metricsOperations = new MetricsOperations( this, this._telemetry, this.GetConfigValueAsTimeSpan(WatchdogConfigSectionName, "MetricInterval", TimeSpan.FromMinutes(5)), cancellationToken); // COMMENTED //this._cleanupOperations = new CleanupOperations(this._telemetry, TimeSpan.FromMinutes(2), cancellationToken) //{ // Endpoint = this.GetConfigValueAsString(WatchdogConfigSectionName, "DiagnosticEndpoint"), // SasToken = this.GetConfigValueAsString(WatchdogConfigSectionName, "DiagnosticSasToken"), // TimeToKeep = this.GetConfigValueAsTimeSpan(WatchdogConfigSectionName, "DiagnosticTimeToKeep", TimeSpan.FromDays(10)), // TimerInterval = this.GetConfigValueAsTimeSpan(WatchdogConfigSectionName, "DiagnosticInterval", TimeSpan.FromMinutes(2)) //}; ServiceEventSource.Current.Trace($"RunAsync INFO: creating the healthcheck operation class"); this._healthCheckOperations = new HealthCheckOperations( this, this._telemetry, this.GetConfigValueAsTimeSpan(WatchdogConfigSectionName, "HealthCheckInterval", TimeSpan.FromMinutes(5)), cancellationToken); // Register the watchdog health check. ServiceEventSource.Current.Trace($"RunAsync:RegisterHealthCheckAsync INFO: RegisterHealthCheckAsync called..."); await this.RegisterHealthCheckAsync(cancellationToken).ConfigureAwait(false); // Loop waiting for cancellation. while (false == cancellationToken.IsCancellationRequested) { // Report the health and metrics of the watchdog to Service Fabric. ServiceEventSource.Current.Trace($"RunAsync:ReportWatchdogHealth INFO: ReportWatchdogHealth called..."); this.ReportWatchdogHealth(); ServiceEventSource.Current.Trace($"RunAsync:ReportWatchdogMetricsAsync INFO: ReportWatchdogMetricsAsync called..."); await this.ReportWatchdogMetricsAsync(cancellationToken); ServiceEventSource.Current.Trace($"RunAsync:ReportClusterHealthAsync INFO: ReportClusterHealthAsync called..."); await this.ReportClusterHealthAsync(cancellationToken); // Delay up to the time for the next health report. await Task.Delay(this.HealthReportInterval, cancellationToken); } }
/// <summary> /// HealthCheckOperations constructor. /// </summary> /// <param name="svc">Reference to WatchdogService stateless service instance.</param> /// <param name="telemetry">Reference to the WatchdogService ReportMetrics instance.</param> /// <param name="interval">TimeSpan of the reporting interval.</param> /// <param name="token">CancellationToken instance.</param> /// <param name="timeout">Default fabric operation timeout value.</param> public HealthCheckOperations( IWatchdogService svc, IWatchdogTelemetry telemetry, TimeSpan interval, CancellationToken token, TimeSpan timeout = default(TimeSpan)) { if (null == svc) { throw new ArgumentNullException("Argument 'svc' is null."); } if (null == telemetry) { throw new ArgumentNullException("Argument 'telemetry' is null."); } ServiceEventSource.Current.ServiceMessage(svc.Context, "HealthCheckOperations.Constructor"); this._token = token; this._service = svc; this._timeout = (default(TimeSpan) == timeout) ? TimeSpan.FromSeconds(5) : timeout; this._telemetry = telemetry; this._http = new HttpClient(); // Create a timer that calls the local method every 30 seconds starting 1 minute from now. this._healthCheckTimer = new Timer( async(o) => { try { await this.EnumerateHealthChecksAsync(); } catch (Exception ex) { this._healthState = HealthState.Error; ServiceEventSource.Current.ServiceMessage(this._service.Context, "Exception {0} in {1}", ex.Message, "HealthCheckTimer method"); } }, this._token, interval, interval.Add(TimeSpan.FromSeconds(30))); }