From 62a4a47373a67387c331fa2927de82d7b44f287d Mon Sep 17 00:00:00 2001 From: Robby Date: Fri, 11 Oct 2024 23:10:01 -0500 Subject: [PATCH] Init --- .../ResourceGroup/ActivityLogReader.cs | 39 +++++++++ BackgroundService/BackgroundService.cs | 86 +++++++++++++++++++ BackgroundService/BackgroundServiceOptions.cs | 4 + Program.cs | 15 ++++ Sentinel.csproj | 16 ++++ appsettings.json | 13 +++ 6 files changed, 173 insertions(+) create mode 100644 Azure.Endpoints/ResourceGroup/ActivityLogReader.cs create mode 100644 BackgroundService/BackgroundService.cs create mode 100644 BackgroundService/BackgroundServiceOptions.cs create mode 100644 Program.cs create mode 100644 Sentinel.csproj create mode 100644 appsettings.json diff --git a/Azure.Endpoints/ResourceGroup/ActivityLogReader.cs b/Azure.Endpoints/ResourceGroup/ActivityLogReader.cs new file mode 100644 index 0000000..bec75a9 --- /dev/null +++ b/Azure.Endpoints/ResourceGroup/ActivityLogReader.cs @@ -0,0 +1,39 @@ +using Microsoft.Extensions.Logging; + +namespace ProperDI.Azure.Endpoints.ResourceGroup.LogLooker; + +public interface IActivityLogReader +{ + Task Scan(CancellationToken cancellationToken); +} + +public class ActivityLogReader : IActivityLogReader +{ + private readonly ILogger _logger; + private readonly HttpClient _httpClient; + + public ActivityLogReader(IHttpClientFactory httpClientFactory, ILogger logger) + { + _httpClient = httpClientFactory.CreateClient() ?? throw new ArgumentNullException(nameof(httpClientFactory)); + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + } + + public async Task Scan(CancellationToken cancellationToken) + { + try + { + var response = await _httpClient.GetAsync("https://ident.me", cancellationToken); + var responseBody = await response.Content.ReadAsStringAsync(); + _logger.LogInformation("Response body: {content}", responseBody); + } + catch (TaskCanceledException) + { + _logger.LogWarning("Task canceled"); + } + catch (System.Exception ex) + { + _logger.LogError(ex, "Http request failed"); + throw; + } + } +} \ No newline at end of file diff --git a/BackgroundService/BackgroundService.cs b/BackgroundService/BackgroundService.cs new file mode 100644 index 0000000..8a20f9f --- /dev/null +++ b/BackgroundService/BackgroundService.cs @@ -0,0 +1,86 @@ +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using ProperDI.Azure.Endpoints.ResourceGroup.LogLooker; + +public class RoleAssesorBackgroundService : IHostedService, IDisposable +{ + private readonly IActivityLogReader _activityLogReader; + private readonly ILogger _logger; + private readonly IOptionsMonitor _options; + private Timer? _timer; + private int _runFrequencyInMinutes; + + public RoleAssesorBackgroundService( + IActivityLogReader activityLogReader, + ILogger logger, + IOptionsMonitor options) + { + _activityLogReader = activityLogReader; + _logger = logger; + _options = options; + + // This sets our initial run frequency + _runFrequencyInMinutes = _options.CurrentValue.RunFrequencyInMinutes; + + // Subscribe to any changes in the config file + _options.OnChange(UpdateTimerInterval); + } + + private void UpdateTimerInterval(RoleAssesorBackgroundServiceOptions options) + { + var newFreq = options.RunFrequencyInMinutes; + + if (newFreq == _runFrequencyInMinutes) + return; + + _runFrequencyInMinutes = newFreq; + _logger.LogInformation("Run frequency updated to {RunFreq} minutes", _runFrequencyInMinutes); + _timer?.Change(TimeSpan.Zero, TimeSpan.FromMinutes(_runFrequencyInMinutes)); + } + + public Task StartAsync(CancellationToken cancellationToken) + { + _logger.LogInformation("Role Assessor background service is starting."); + + _timer = new Timer(async _ => await ProcessAsync(cancellationToken), null, TimeSpan.Zero, TimeSpan.FromMinutes(1)); + + return Task.CompletedTask; + } + + private async Task ProcessAsync(CancellationToken cancellationToken) + { + try + { + _logger.LogInformation("Role Assessor background service is running at: {time}", DateTimeOffset.Now); + + if (cancellationToken.IsCancellationRequested) + return; + + await _activityLogReader.Scan(cancellationToken); + } + catch (OperationCanceledException) + { + _logger.LogInformation("Operation was canceled"); + } + catch (System.Exception ex) + { + _logger.LogError(ex, "An error occurred while reading the logs"); + throw; + } + } + + public Task StopAsync(CancellationToken cancellationToken) + { + _logger.LogInformation("Stopping the Role Assessor background service."); + + _timer?.Change(Timeout.Infinite, 0); + + return Task.CompletedTask; + } + + public void Dispose() + { + _timer?.Dispose(); + } +} \ No newline at end of file diff --git a/BackgroundService/BackgroundServiceOptions.cs b/BackgroundService/BackgroundServiceOptions.cs new file mode 100644 index 0000000..7213ce7 --- /dev/null +++ b/BackgroundService/BackgroundServiceOptions.cs @@ -0,0 +1,4 @@ +public class RoleAssesorBackgroundServiceOptions +{ + public int RunFrequencyInMinutes { get; set; } = 5; // Defaults to 5 minute. +} \ No newline at end of file diff --git a/Program.cs b/Program.cs new file mode 100644 index 0000000..db42d63 --- /dev/null +++ b/Program.cs @@ -0,0 +1,15 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using ProperDI.Azure.Endpoints.ResourceGroup.LogLooker; + +HostApplicationBuilder builder = Host.CreateApplicationBuilder(args); + +builder.Services.AddHttpClient(); +builder.Services.AddTransient(); + +builder.Services.Configure(builder.Configuration.GetSection("RoleAssessorBackgroundService")); +builder.Services.AddHostedService(); + +var host = builder.Build(); + +await host.RunAsync(); \ No newline at end of file diff --git a/Sentinel.csproj b/Sentinel.csproj new file mode 100644 index 0000000..abf59c4 --- /dev/null +++ b/Sentinel.csproj @@ -0,0 +1,16 @@ + + + + Exe + net8.0 + enable + enable + + + + + + + + + diff --git a/appsettings.json b/appsettings.json new file mode 100644 index 0000000..c2e212f --- /dev/null +++ b/appsettings.json @@ -0,0 +1,13 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information", + "System.Net": "Warning" + } + }, + "RoleAssessorBackgroundService": { + "RunFrequencyInMinutes": 12 + } +} \ No newline at end of file