Skip to content

Commit

Permalink
add option to error log to table storage #314
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffputz committed Oct 1, 2022
1 parent 7942781 commit bb45c24
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 7 deletions.
13 changes: 11 additions & 2 deletions docs/azurekitlibrary.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ The `PopForums.AzureKit` library makes it possible to wire up the following scen
* Using Azure Storage queues and Functions to queue work for search indexing, emailing and scoring game award calculation
* Using Azure Storage for image uploads
* Using Azure Search
* Using Azure storage for hosting uploaded images in posts
* Using Azure Storage for hosting uploaded images in posts
* Using Azure Table Storage for error logging

You don't need to use the AzureKit components to run in an Azure App Service. These components are intended for making scale-out possible. The web app can run self-contained in a single node on an Azure App Service without these optional bits.

Expand Down Expand Up @@ -213,4 +214,12 @@ services.AddPopForumsAzureBlobStorageForPostImages();
```
It's important to note that `PopForums.AzureKit.Functions` is already wired to use the blob storage `IPostImageRepository` version, because it's assumed that if you're already using an Azure queue, you also have a storage account.

Another thing to keep in mind is that if you're working locally, and your Azurite instance doesn't have `https` configured, it will break because most browsers do not allow non-`https` images to appear in a secure page. The simplest work around for this is not to install a local certificate, but to change your launch settings for the web app to not run on `https`.
Another thing to keep in mind is that if you're working locally, and your Azurite instance doesn't have `https` configured, it will break because most browsers do not allow non-`https` images to appear in a secure page. The simplest work around for this is not to install a local certificate, but to change your launch settings for the web app to not run on `https`.

## Using Azure Table Storage for error logging

You may prefer to do your error logging to Azure Table Storage instead of the SQL database. You can do this by adding one line to your `Program` file, which swaps out the SQL error repository for the table storage:
```
services.AddPopForumsTableStorageLogging();
```
The one limitation here is that you can't use the admin UI to look at errors, since paging and ordering is fairly crude in table storage. For the connection string, it will use whatever is found in `PopForums:Storage:ConnectionString`, the same setting used by the image uploads.
1 change: 1 addition & 0 deletions docs/versionhistory.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Here's a partial version history that shows how POP Forums has evolved over the
* Remove composite activity feed #299
* Use fulltext editor for profile signatures #291
* Decommission email from profile #310
* Add option to write error log to table storage #314
* Refactor: Move all of the client stuff to the `Mvc` project, ditch the npm package #285
* Refactor: Update MailKit library to v3.x #268
* Refactor: Update ImageSharp library to v2.x #267
Expand Down
5 changes: 4 additions & 1 deletion src/PopForums.AzureKit.Functions/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@
s.AddTransient<INotificationTunnel, NotificationTunnel>();
s.RemoveAll<IPostImageRepository>();
s.AddTransient<IPostImageRepository, PopForums.AzureKit.PostImage.PostImageRepository>();


// use Azure table storage for logging instead of database
//s.AddPopForumsTableStorageLogging();

switch (config.SearchProvider.ToLower())
{
case "elasticsearch":
Expand Down
83 changes: 83 additions & 0 deletions src/PopForums.AzureKit/Logging/ErrorLogRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
using PopForums.Configuration;
using PopForums.Models;
using PopForums.Repositories;
using PopForums.Services;
using System.Collections.Generic;
using System.Threading.Tasks;
using System;
using Azure.Data.Tables;

namespace PopForums.AzureKit.Logging;

public class ErrorLogRepository : IErrorLogRepository
{
private readonly ITenantService _tenantService;
private readonly IConfig _config;
private const string ErrorTableName = "pferrorlog";
private TableClient _tableClient;

public ErrorLogRepository(ITenantService tenantService, IConfig config)
{
_tenantService = tenantService;
_config = config;
}

public async Task<ErrorLogEntry> Create(DateTime timeStamp, string message, string stackTrace, string data, ErrorSeverity severity)
{
var tableClient = await GetTableClient();
var errorLog = new ErrorLogEntry
{
ErrorID = 0,
TimeStamp = timeStamp,
Message = message,
StackTrace = stackTrace,
Data = data,
Severity = severity
};
var tenantID = _tenantService.GetTenant();
var rowKey = DateTime.UtcNow.ToString("s") + Random.Shared.Next(100000,999999);
var entry = new TableEntity($"{DateTime.UtcNow.Year}-{DateTime.UtcNow.DayOfYear.ToString("D3")}", rowKey)
{
{ "TenantID", tenantID },
{ "Message", errorLog.Message },
{ "StackTrace", errorLog.StackTrace },
{ "Data", errorLog.Data },
{ "Severity", errorLog.Severity.ToString() }
};
await tableClient.AddEntityAsync(entry);
return errorLog;
}

private async Task<TableClient> GetTableClient()
{
if (_tableClient != null)
return _tableClient;
var tableClient = new TableClient(_config.StorageConnectionString, ErrorTableName);
await tableClient.CreateIfNotExistsAsync();
_tableClient = tableClient;
return tableClient;
}

public Task<int> GetErrorCount()
{
return Task.FromResult(1);
}

public Task<List<ErrorLogEntry>> GetErrors(int startRow, int pageSize)
{
var entry = new ErrorLogEntry {Message = "Check table storage for errors."};
var list = new List<ErrorLogEntry> {entry};
return Task.FromResult(list);
}

public Task DeleteError(int errorID)
{
throw new NotImplementedException();
}

public async Task DeleteAllErrors()
{
var tableClient = new TableClient(_config.StorageConnectionString, ErrorTableName);
await tableClient.DeleteAsync();
}
}
5 changes: 1 addition & 4 deletions src/PopForums.AzureKit/PopForums.AzureKit.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Azure.Data.Tables" Version="12.6.1" />
<PackageReference Include="Azure.Search.Documents" Version="11.3.0" />
<PackageReference Include="Azure.Storage.Blobs" Version="12.13.1" />
<PackageReference Include="Azure.Storage.Queues" Version="12.11.1" />
Expand All @@ -31,8 +32,4 @@
<PackageReference Include="System.Text.Json" Version="6.0.5" />
</ItemGroup>

<ItemGroup>
<Folder Include="PostImage\" />
</ItemGroup>

</Project>
6 changes: 6 additions & 0 deletions src/PopForums.AzureKit/ServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,10 @@ public static IServiceCollection AddPopForumsAzureBlobStorageForPostImages(this
services.Replace(ServiceDescriptor.Transient<IPostImageRepository, PopForums.AzureKit.PostImage.PostImageRepository>());
return services;
}

public static IServiceCollection AddPopForumsTableStorageLogging(this IServiceCollection services)
{
services.Replace(ServiceDescriptor.Transient<IErrorLogRepository, PopForums.AzureKit.Logging.ErrorLogRepository>());
return services;
}
}
3 changes: 3 additions & 0 deletions src/PopForums.Web/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@
// this adds dependencies from the MVC project (and base dependencies) and sets up authentication for the forum
services.AddPopForumsMvc();

// use Azure table storage for logging instead of database
//services.AddPopForumsTableStorageLogging();

// use Redis cache for POP Forums using AzureKit
//services.AddPopForumsRedisCache();

Expand Down

0 comments on commit bb45c24

Please sign in to comment.