From 3f46ab6d373acdd7b094f1ad9cbb7dcb4dddf29f Mon Sep 17 00:00:00 2001 From: Collin Barrett Date: Mon, 13 Aug 2018 18:14:37 -0500 Subject: [PATCH] add email notifications for SnapshotService errors ref #12 --- src/FilterLists.Agent/Program.cs | 2 +- src/FilterLists.Agent/appsettings.json | 15 +++++++- src/FilterLists.Api/appsettings.json | 15 +++++++- .../Extensions/ConfigureServicesCollection.cs | 1 + src/FilterLists.Services/EmailService.cs | 38 +++++++++++++++++++ .../FilterLists.Services.csproj | 1 + src/FilterLists.Services/Service.cs | 9 +++++ .../Snapshot/SnapshotDe.cs | 28 +++++++++++++- .../Snapshot/SnapshotService.cs | 7 ++-- 9 files changed, 106 insertions(+), 10 deletions(-) create mode 100644 src/FilterLists.Services/EmailService.cs diff --git a/src/FilterLists.Agent/Program.cs b/src/FilterLists.Agent/Program.cs index e215ddd4e..7fc5cc265 100644 --- a/src/FilterLists.Agent/Program.cs +++ b/src/FilterLists.Agent/Program.cs @@ -28,7 +28,7 @@ public static void Main() private static void BuildConfigurationRoot() => configurationRoot = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) - .AddJsonFile("appsettings.json", true) + .AddJsonFile("appsettings.json", false) .Build(); private static void InstantiateTelemetryClient() diff --git a/src/FilterLists.Agent/appsettings.json b/src/FilterLists.Agent/appsettings.json index d3f5ba20b..9dfea0c64 100644 --- a/src/FilterLists.Agent/appsettings.json +++ b/src/FilterLists.Agent/appsettings.json @@ -6,10 +6,21 @@ */ { "ApplicationInsights": { - "InstrumentationKey": "InstrumentationKeyValue" + "InstrumentationKey": "" }, "ConnectionStrings": { - "FilterListsConnection": "FilterListsConnectionValue" + "FilterListsConnection": "" + }, + "SendGrid": { + "ApiKey": "", + "From": { + "Name": "", + "EmailAddress": "" + }, + "To": { + "Name": "", + "EmailAddress": "" + } }, "DataDirectory": { "Path": "..\\..\\data" diff --git a/src/FilterLists.Api/appsettings.json b/src/FilterLists.Api/appsettings.json index d3f5ba20b..9dfea0c64 100644 --- a/src/FilterLists.Api/appsettings.json +++ b/src/FilterLists.Api/appsettings.json @@ -6,10 +6,21 @@ */ { "ApplicationInsights": { - "InstrumentationKey": "InstrumentationKeyValue" + "InstrumentationKey": "" }, "ConnectionStrings": { - "FilterListsConnection": "FilterListsConnectionValue" + "FilterListsConnection": "" + }, + "SendGrid": { + "ApiKey": "", + "From": { + "Name": "", + "EmailAddress": "" + }, + "To": { + "Name": "", + "EmailAddress": "" + } }, "DataDirectory": { "Path": "..\\..\\data" diff --git a/src/FilterLists.Services/DependencyInjection/Extensions/ConfigureServicesCollection.cs b/src/FilterLists.Services/DependencyInjection/Extensions/ConfigureServicesCollection.cs index 778dac7d9..1b6bcd362 100644 --- a/src/FilterLists.Services/DependencyInjection/Extensions/ConfigureServicesCollection.cs +++ b/src/FilterLists.Services/DependencyInjection/Extensions/ConfigureServicesCollection.cs @@ -35,6 +35,7 @@ public static void AddFilterListsAgentServices(this IServiceCollection services, x => x.MigrationsAssembly("FilterLists.Api")) .EnableSensitiveDataLogging()); services.TryAddScoped(); + services.TryAddScoped(); services.AddAutoMapper(); } } diff --git a/src/FilterLists.Services/EmailService.cs b/src/FilterLists.Services/EmailService.cs new file mode 100644 index 000000000..3fffee25f --- /dev/null +++ b/src/FilterLists.Services/EmailService.cs @@ -0,0 +1,38 @@ +using System.Threading.Tasks; +using JetBrains.Annotations; +using Microsoft.Extensions.Configuration; +using SendGrid; +using SendGrid.Helpers.Mail; + +namespace FilterLists.Services +{ + [UsedImplicitly] + public class EmailService + { + private readonly SendGridClient sendGridClient; + private readonly EmailAddress fromEmailAddress; + private readonly EmailAddress toEmailAddress; + + public EmailService(IConfiguration configuration) + { + var sendGridConfig = configuration.GetSection("SendGrid"); + sendGridClient = new SendGridClient(sendGridConfig.GetValue("ApiKey")); + fromEmailAddress = new EmailAddress(sendGridConfig.GetSection("From").GetValue("EmailAddress"), + sendGridConfig.GetSection("From").GetValue("Name")); + toEmailAddress = new EmailAddress(sendGridConfig.GetSection("To").GetValue("EmailAddress"), + sendGridConfig.GetSection("To").GetValue("Name")); + } + + public async Task SendEmailAsync(string subjectBody, string message) + { + var msg = new SendGridMessage + { + From = fromEmailAddress, + Subject = "[FilterLists] " + subjectBody, + PlainTextContent = message + }; + msg.AddTo(toEmailAddress); + await sendGridClient.SendEmailAsync(msg); + } + } +} \ No newline at end of file diff --git a/src/FilterLists.Services/FilterLists.Services.csproj b/src/FilterLists.Services/FilterLists.Services.csproj index 081bc0518..6eb37a229 100644 --- a/src/FilterLists.Services/FilterLists.Services.csproj +++ b/src/FilterLists.Services/FilterLists.Services.csproj @@ -20,6 +20,7 @@ + diff --git a/src/FilterLists.Services/Service.cs b/src/FilterLists.Services/Service.cs index 702feefbf..6f7f9dd50 100644 --- a/src/FilterLists.Services/Service.cs +++ b/src/FilterLists.Services/Service.cs @@ -9,6 +9,7 @@ public class Service { protected readonly IConfigurationProvider ConfigurationProvider; protected readonly FilterListsDbContext DbContext; + protected readonly EmailService EmailService; public Service(FilterListsDbContext dbContext) => DbContext = dbContext; @@ -17,5 +18,13 @@ public Service(FilterListsDbContext dbContext, IConfigurationProvider configurat DbContext = dbContext; ConfigurationProvider = configurationProvider; } + + public Service(FilterListsDbContext dbContext, IConfigurationProvider configurationProvider, + EmailService emailService) + { + DbContext = dbContext; + ConfigurationProvider = configurationProvider; + EmailService = emailService; + } } } \ No newline at end of file diff --git a/src/FilterLists.Services/Snapshot/SnapshotDe.cs b/src/FilterLists.Services/Snapshot/SnapshotDe.cs index ac799bc71..a47c70ab3 100644 --- a/src/FilterLists.Services/Snapshot/SnapshotDe.cs +++ b/src/FilterLists.Services/Snapshot/SnapshotDe.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Net; using System.Net.Http; +using System.Text; using System.Threading.Tasks; using FilterLists.Data; using FilterLists.Data.Entities.Junctions; @@ -18,12 +19,14 @@ public class SnapshotDe private const int BatchSize = 1000; private readonly FilterListsDbContext dbContext; + private readonly EmailService emailService; private readonly FilterListViewUrlDto list; private Data.Entities.Snapshot snapshot; - public SnapshotDe(FilterListsDbContext dbContext, FilterListViewUrlDto list) + public SnapshotDe(FilterListsDbContext dbContext, EmailService emailService, FilterListViewUrlDto list) { this.dbContext = dbContext; + this.emailService = emailService; this.list = list; } @@ -62,12 +65,14 @@ private async Task TryGetContent() catch (WebException we) { snapshot.HttpStatusCode = ((int)((HttpWebResponse)we.Response).StatusCode).ToString(); + await SendWebExceptionEmail(); return null; } - catch (Exception) + catch (Exception e) { //TODO: log exception (#148) snapshot.HttpStatusCode = null; + await SendExceptionEmail(e); return null; } } @@ -85,9 +90,28 @@ private async Task GetContent() } } + await SendWebExceptionEmail(); return null; } + private async Task SendWebExceptionEmail() + { + var message = new StringBuilder(); + message.AppendLine("Snapshot WebException"); + message.AppendLine("FilterListId: " + snapshot.FilterList.Id); + message.AppendLine("HTTP Status Code: " + snapshot.HttpStatusCode); + await emailService.SendEmailAsync("Snapshot WebException", message.ToString()); + } + + private async Task SendExceptionEmail(Exception e) + { + var message = new StringBuilder(); + message.AppendLine("Snapshot Exception"); + message.AppendLine("FilterListId: " + snapshot.FilterList.Id); + message.AppendLine("Exception: " + e.Message); + await emailService.SendEmailAsync("Snapshot Exception", message.ToString()); + } + private async Task SaveSnapshotInBatches(string content) { var rawRules = GetRawRules(content); diff --git a/src/FilterLists.Services/Snapshot/SnapshotService.cs b/src/FilterLists.Services/Snapshot/SnapshotService.cs index 1e2b302d7..71b59095b 100644 --- a/src/FilterLists.Services/Snapshot/SnapshotService.cs +++ b/src/FilterLists.Services/Snapshot/SnapshotService.cs @@ -19,8 +19,9 @@ public class SnapshotService : Service private static readonly IList IgnoreLists = new ReadOnlyCollection(new List {48, 149, 173, 185, 186, 187, 188, 189, 352}); - public SnapshotService(FilterListsDbContext dbContext, IConfigurationProvider configurationProvider) - : base(dbContext, configurationProvider) + public SnapshotService(FilterListsDbContext dbContext, IConfigurationProvider configurationProvider, + EmailService emailService) + : base(dbContext, configurationProvider, emailService) { } @@ -54,7 +55,7 @@ await DbContext .ToListAsync(); private IEnumerable GetSnapshots(IEnumerable lists) => - lists.Select(list => new SnapshotDe(DbContext, list)); + lists.Select(list => new SnapshotDe(DbContext, EmailService, list)); private static async Task SaveSnapshots(IEnumerable snapshots) {