UKHO.Logging.EventHubLogProvider
1.24067.2
dotnet add package UKHO.Logging.EventHubLogProvider --version 1.24067.2
NuGet\Install-Package UKHO.Logging.EventHubLogProvider -Version 1.24067.2
<PackageReference Include="UKHO.Logging.EventHubLogProvider" Version="1.24067.2" />
paket add UKHO.Logging.EventHubLogProvider --version 1.24067.2
#r "nuget: UKHO.Logging.EventHubLogProvider, 1.24067.2"
// Install UKHO.Logging.EventHubLogProvider as a Cake Addin
#addin nuget:?package=UKHO.Logging.EventHubLogProvider&version=1.24067.2
// Install UKHO.Logging.EventHubLogProvider as a Cake Tool
#tool nuget:?package=UKHO.Logging.EventHubLogProvider&version=1.24067.2
Event Hub Log Provider
The Event Hub Log Provider provides a logging sink for the Microsoft.Extensions.Logging.Abstractions. Logs are sent to Event Hub as a JSON message. The EventHubLogProvider provides a number of standard properties to enrich every log message, and provides a mechanism to add application specific custom properties to logs.
Getting Started
Installation Guide
This package is available from NuGet: UKHO.Logging.EventHubLogProvider
nuget install UKHO.Logging.EventHubLogProvider
There are two recommended setups depending on the version of .NET: a legacy setup for .NET Core, and a setup for .NET 5/6+.
.NET 5/6+ Setup
The EventHubLogProvider is added to the IServiceCollection
service collection via an ILoggingBuilder
.
NuGet packages can be installed for extensions to the builder, for example adding console logging in the below statement loggingBuilder.AddConsole();
would require installing the package ConsoleLoggerExtensions
services.AddLogging(loggingBuilder =>
{
loggingBuilder.AddConfiguration(configuration.GetSection("Logging"));
loggingBuilder.AddConsole();
loggingBuilder.AddDebug();
loggingBuilder.AddAzureWebAppDiagnostics();
var eventHubLoggingConfiguration = new EventHubLoggingConfiguration();
configuration.GetSection(EventHubLoggingConfiguration.ConfigSection).Bind(eventHubLoggingConfiguration);
if (!string.IsNullOrEmpty(eventHubLoggingConfiguration.ConnectionString))
{
loggingBuilder.AddEventHub(options =>
{
options.Environment = eventHubLoggingConfiguration.Environment;
options.DefaultMinimumLogLevel = (LogLevel)Enum.Parse(typeof(LogLevel), eventHubLoggingConfiguration.MinimumLoggingLevel, true);
options.MinimumLogLevels["UKHO"] = (LogLevel)Enum.Parse(typeof(LogLevel), eventHubLoggingConfiguration.UkhoMinimumLoggingLevel, true);
options.EventHubConnectionString = eventHubLoggingConfiguration.ConnectionString;
options.EventHubEntityPath = eventHubLoggingConfiguration.EntityPath;
options.System = eventHubLoggingConfiguration.System;
options.Service = eventHubLoggingConfiguration.Service;
options.NodeName = eventHubLoggingConfiguration.NodeName;
options.AdditionalValuesProvider = ConfigAdditionalValuesProvider;
});
}
});
If you've upgraded from an earlier version of .NET Core and have not migrated to the new minimal hosting model, i.e., there is still a startup.cs, the above code should be added to the ConfigureServices
:
public void ConfigureServices(IServiceCollection services)
{
services.AddLogging(loggingBuilder =>
{
...
}
An HttpContextAccessor
is unavailable in the ConfigureServices
method, however, a reference to it can be acquired in the Configure
method:
public class Startup
{
private readonly IConfiguration configuration;
private IHttpContextAccessor _httpContextAccessor;
...
public void Configure(IApplicationBuilder app,
IWebHostEnvironment env
IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
...
Then, the additional values can be gathered as follows:
private void ConfigAdditionalValuesProvider(IDictionary<string, object> additionalValues)
{
if (_httpContextAccessor.HttpContext != null)
{
additionalValues["_RemoteIPAddress"] =
_httpContextAccessor.HttpContext.Connection.RemoteIpAddress?.ToString();
additionalValues["_User-Agent"] =
_httpContextAccessor.HttpContext.Request.Headers["User-Agent"].FirstOrDefault() ?? string.Empty;
additionalValues["_AssemblyVersion"] = Assembly
.GetExecutingAssembly()
.GetCustomAttributes<AssemblyFileVersionAttribute>().Single()
.Version;
additionalValues["_X-Correlation-ID"] =
_httpContextAccessor.HttpContext.Request.Headers?[""].FirstOrDefault() ?? string.Empty;
}
}
Legacy .NET Core Setup
The EventHubLogProvider is added to a LoggerFactory as follows:
var connectionString = ""; //Connection string to Event Hub with write permissions.
var entityPath = ""; //Event Hub entity path.
loggerFactory.AddEventHub(
config =>
{
/*
optional(AzureStorageLogProviderOptions)
Setting this property and setting ("AzureStorageOptions:Enabled") = true
enables the azure storage logging provider
(for messages with size >= 1Mb)
Please check "Azure Storage Logging Provider" for more information.
*/
config.AzureStorageLogProviderOptions = new AzureStorageLogProviderOptions(
Configuration.GetValue<String>("AzureStorageOptions:SasUrl")
,Configuration.GetValue<Boolean>("AzureStorageOptions:Enabled")
,Configuration.GetValue<String> ("AzureStorageOptions:SuccessfulMessageTemplate")
,Configuration.GetValue<String>("AzureStorageOptions:FailedMessageTemplate")
);
config.Environment = "Production";
config.DefaultMinimumLogLevel = LogLevel.Warning;
config.MinimumLogLevels["Microsoft.AspNetCore"] = LogLevel.Trace;
config.MinimumLogLevels["Microsoft.AspNetCore.Server"] = LogLevel.Error;
config.EventHubConnectionString = connectionString;
config.EventHubEntityPath = entityPath;
config.System = "My System Name";
config.Service = "My Service Name";
config.NodeName = "Node 123";
config.AdditionalValuesProvider = additionalValues =>
{
additionalValues["_AssemblyVersion"] = Assembly.GetExecutingAssembly()
.GetCustomAttributes<AssemblyFileVersionAttribute>().Single().Version;
additionalValues["_X-Correlation-ID"] = correlationId;
};
config.ValidateConnectionString = true;
});
Within a standard ASP .Net Core project, this provider is best added in the Start-up's Configure
method as this will allow access to a IHttpContextAccessor
for injecting request data to all logs.
public void Configure(IApplicationBuilder app,
IHostingEnvironment env,
ILoggerFactory loggerFactory,
IHttpContextAccessor httpContextAccessor)
{
...
loggerFactory.AddConsole();
loggerFactory.AddEventHub(
config =>
{
/*
optional(AzureStorageLogProviderOptions)
Setting this property and setting ("AzureStorageOptions:Enabled") = true
enables the azure storage logging provider
(for messages with size >= 1Mb)
Please check "Azure Storage Logging Provider" for more information.
*/
config.AzureStorageLogProviderOptions = new AzureStorageLogProviderOptions(
Configuration.GetValue<String>("AzureStorageOptions:SasUrl")
,Configuration.GetValue<Boolean>("AzureStorageOptions:Enabled")
,Configuration.GetValue<String> ("AzureStorageOptions:SuccessfulMessageTemplate")
,Configuration.GetValue<String>("AzureStorageOptions:FailedMessageTemplate")
);
config.Environment = "Production";
config.DefaultMinimumLogLevel = LogLevel.Warning;
config.MinimumLogLevels["Microsoft.AspNetCore"] = LogLevel.Trace;
config.MinimumLogLevels["Microsoft.AspNetCore.Server"] = LogLevel.Error;
config.EventHubConnectionString = connectionString;
config.EventHubEntityPath = entityPath;
config.System = "My System Name";
config.Service = "My Service Name";
config.NodeName = "Node 123";
config.AdditionalValuesProvider = additionalValues =>
{
additionalValues["_AssemblyVersion"] = Assembly.GetExecutingAssembly()
.GetCustomAttributes<AssemblyFileVersionAttribute>().Single().Version;
additionalValues["_X-Correlation-ID"] = correlationId;
additionalValues["_RemoteIPAddress"] = httpContextAccessor.HttpContext.Connection.RemoteIpAddress.ToString();
additionalValues["_User-Agent"] = httpContextAccessor.HttpContext.Request.Headers["User-Agent"].FirstOrDefault() ?? string.Empty;
};
config.ValidateConnectionString = true;
});
}
Customisation of Log Parameter Serialization
The default log parameter serialization uses NewtonSoft.Net JsonConvert to serialize the log parameters to JSON. On occasion, it maybe desirable to customise the JSON produced to control how individual properties are serialized. This can be done by providing custom converters that extend the Newtonsoft.Json.JsonConverter
class:
loggerFactory.AddEventHub(
config =>
{
...
config.CustomLogSerializerConverters = new List<JsonConverter> { new VersionJsonConverter() };
...
});
The JsonConverter must implement WriteJson
, but the ReadJson
method can be left unimplemented and the CanRead
property can return false. The CanConvert
method must only return true for the types that you wish to override the serialization of. More details about custom converters can be found in the JsonConvert documentation https://www.newtonsoft.com/json/help/html/CustomJsonConverter.htm.
public class VersionJsonConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value is Version version)
{
writer.WriteValue($"{version.MajorVersion}.{version.MinorVersion}.{version.Build}.{version.Revision}");
}
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Version);
}
public override bool CanRead => false;
}
Azure Storage Logging Provider
The Azure Storage Logging Provider is a storage logging provider that stores messages with size equal or greater than 1Mb into an Azure storage container. Finally, it updates the log entry with the azure storage blob details. Enabling the Azure storage provider is optional.
The provider can be enabled by providing the AzureStorageLogProviderOptions model which consists of:
//The SAS url for the storage container, recommended rights set : racwl
string azureStorageContainerSasUrlString
//Enables (true) or disables(false) the Azure storage logging provider
bool azureStorageLoggerEnabled,
//A template for the messages that are successfully stored*
string successfulMessageTemplate,
//A template for the messages that failed to be stored*
string failedMessageTemplate
/*
The templates are configurable.
The parameters must be added with the following format: {{property_name}}
Available properties:
<param name="reasonPhrase">The result reason phrase</param>
<param name="statusCode">The http status code</param>
<param name="requestId">The client request Id</param>
<param name="fileSHA">The blob SHA 256</param>
<param name="isStored">The flag that determines if the result was successful/failed</param>
<param name="blobFullName">The blob full name</param>
<param name="fileSize">The file size (optional)</param>
<param name="modifiedDate">The modified date(optional)</param>
public string ReasonPhrase { get; set; }
public int StatusCode { get; set; }
public string RequestId { get; set; }
public string FileSHA { get; set; }
public bool IsStored { get; set; }
public string BlobFullName { get; set; }
public long FileSize { get; set; }
public DateTime ModifiedDate { get; set; }
*/
Example of a configuration section(json)
"AzureStorageOptions": {
"SasUrl": "the_sas_url", //removed for security reasons
"Enabled": true,
"SuccessfulMessageTemplate": "Azure Storage Logging: A blob with the error details was created at {{BlobFullName}}. Reason: ErrorMessageEqualOrGreaterTo1MB ResponseMessage: {{ReasonPhrase}} ResponseCode: {{StatusCode}} RequestId: {{RequestId}} Sha256: {{FileSHA}} FileSize(Bs): {{FileSize}} FileModifiedDate: {{ModifiedDate}}",
"FailedMessageTemplate": "Azure Storage Logging: Storing blob failed. Reason: ErrorMessageEqualOrGreaterTo1MB ResponseMessage: {{ReasonPhrase}} ResponseCode: {{StatusCode}} RequestId: {{RequestId}}"
}
Azure Storage Provider Functional Diagram
The diagram (Visio) can be downloaded using the following link
EventHub Logging Provider Help File
How to Engage, Contribute, and Give Feedback
Some of the best ways to contribute are to try things out, file issues and make pull-requests.
The UK Hydrographic Office (UKHO) supplies hydrographic information to protect lives at sea. Maintaining the confidentially, integrity and availability of our services is paramount. Found a security bug? Please report it to us at UKHO-ITSO@gov.co.uk
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 is compatible. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.8
- Azure.Messaging.EventHubs (>= 5.9.2)
- Azure.Storage.Blobs (>= 12.13.0)
- Microsoft.Azure.Amqp (>= 2.6.3)
- Microsoft.Extensions.Logging (>= 7.0.0)
- Newtonsoft.Json (>= 13.0.2)
- System.Configuration.ConfigurationManager (>= 4.7.0)
-
.NETStandard 2.0
- Azure.Messaging.EventHubs (>= 5.9.2)
- Azure.Storage.Blobs (>= 12.13.0)
- Microsoft.Azure.Amqp (>= 2.6.3)
- Microsoft.Extensions.Logging (>= 7.0.0)
- Newtonsoft.Json (>= 13.0.2)
- System.Configuration.ConfigurationManager (>= 4.7.0)
-
net6.0
- Azure.Messaging.EventHubs (>= 5.9.2)
- Azure.Storage.Blobs (>= 12.13.0)
- Microsoft.Azure.Amqp (>= 2.6.3)
- Microsoft.Extensions.Logging (>= 7.0.0)
- Newtonsoft.Json (>= 13.0.2)
- System.Configuration.ConfigurationManager (>= 4.7.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
1.24067.2 | 528 | 3/7/2024 |
1.23242.1 | 1,732 | 8/30/2023 |
1.23073.7 | 1,953 | 3/14/2023 |
1.22356.5 | 844 | 12/22/2022 |
1.22356.1 | 375 | 12/22/2022 |
1.22220.1 | 1,319 | 8/8/2022 |
1.22217.9 | 439 | 8/8/2022 |
1.22047.3 | 1,731 | 2/16/2022 |
1.22047.1 | 591 | 2/16/2022 |
1.20077.2 | 2,054 | 3/17/2020 |
1.20013.11 | 612 | 1/13/2020 |
1.20013.5 | 573 | 1/13/2020 |