Add project files.
This commit is contained in:
43
Core.Blueprint.Logging/Adapters/ErrorDetails.cs
Normal file
43
Core.Blueprint.Logging/Adapters/ErrorDetails.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
// ***********************************************************************
|
||||
// <copyright file="ErrorDetailsDto.cs">
|
||||
// Heath
|
||||
// </copyright>
|
||||
// ***********************************************************************
|
||||
|
||||
using System.ComponentModel;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Core.Blueprint.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// The service error details transfer object.
|
||||
/// </summary>
|
||||
public class ErrorDetails
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the service error code.
|
||||
/// </summary>
|
||||
/// <example>healthy</example>
|
||||
[DisplayName(DisplayNames.ErrorCode)]
|
||||
[JsonPropertyName(DisplayNames.ErrorCode)]
|
||||
public string? ErrorCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the service error message.
|
||||
/// </summary>
|
||||
/// <example>This is an example message.</example>
|
||||
[DisplayName(DisplayNames.Message)]
|
||||
[JsonPropertyName(DisplayNames.Message)]
|
||||
public string? Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the service target.
|
||||
/// </summary>
|
||||
/// <example>healthy</example>
|
||||
[DisplayName(DisplayNames.Target)]
|
||||
[JsonPropertyName(DisplayNames.Target)]
|
||||
public string? Target { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
45
Core.Blueprint.Logging/Adapters/HttpError.cs
Normal file
45
Core.Blueprint.Logging/Adapters/HttpError.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
// ***********************************************************************
|
||||
// <copyright file="HttpErrorDto.cs">
|
||||
// Heath
|
||||
// </copyright>
|
||||
// ***********************************************************************
|
||||
|
||||
using System.ComponentModel;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Core.Blueprint.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// The service HTTP error data transfer object.
|
||||
/// </summary>
|
||||
public class HttpError
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the error.
|
||||
/// </summary>
|
||||
[DisplayName(DisplayNames.Error)]
|
||||
[JsonPropertyName(DisplayNames.Error)]
|
||||
public ErrorDetails Error { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="HttpError{TMessage}"/>
|
||||
/// with custom parameters.
|
||||
/// </summary>
|
||||
/// <param name="message">The HTTP error message.</param>
|
||||
/// <param name="errorCode">The HTTP error code.</param>
|
||||
/// <param name="target">The HTTP error target.</param>
|
||||
public HttpError(
|
||||
string? message,
|
||||
string? errorCode,
|
||||
string? target)
|
||||
{
|
||||
Error = new ErrorDetails
|
||||
{
|
||||
ErrorCode = errorCode,
|
||||
Message = message,
|
||||
Target = target,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
41
Core.Blueprint.Logging/Adapters/HttpException.cs
Normal file
41
Core.Blueprint.Logging/Adapters/HttpException.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
// ***********************************************************************
|
||||
// <copyright file="HttpException.cs">
|
||||
// Heath
|
||||
// </copyright>
|
||||
// ***********************************************************************
|
||||
|
||||
namespace Core.Blueprint.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// The service HTTP exception.
|
||||
/// Extends the <see cref="Exception"/> class.
|
||||
/// </summary>
|
||||
public class HttpException : Exception
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the exception error code.
|
||||
/// </summary>
|
||||
public string? ErrorCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the exception status code.
|
||||
/// </summary>
|
||||
public int StatusCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="HttpException"/>.
|
||||
/// </summary>
|
||||
/// <param name="statusCode">The exception status code.</param>
|
||||
/// <param name="errorCode">The exception error code.</param>
|
||||
/// <param name="message">The exception message.</param>
|
||||
public HttpException(
|
||||
int statusCode,
|
||||
string errorCode,
|
||||
string message)
|
||||
: base(message)
|
||||
{
|
||||
ErrorCode = errorCode;
|
||||
StatusCode = statusCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
120
Core.Blueprint.Logging/Adapters/LogDetail.cs
Normal file
120
Core.Blueprint.Logging/Adapters/LogDetail.cs
Normal file
@@ -0,0 +1,120 @@
|
||||
// ***********************************************************************
|
||||
// <copyright file="LogDetail.cs">
|
||||
// Heath
|
||||
// </copyright>
|
||||
// ***********************************************************************
|
||||
|
||||
using System.ComponentModel;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Core.Blueprint.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// The service logger detail object.
|
||||
/// </summary>
|
||||
/// <typeparam name="TMessage">The generic message type.</typeparam>
|
||||
public class LogDetail<TMessage>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the log severity.
|
||||
/// </summary>
|
||||
/// <example>info</example>
|
||||
[DisplayName(DisplayNames.Severity)]
|
||||
[JsonPropertyName(DisplayNames.Severity)]
|
||||
public LogSeverity Severity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the timestamp.
|
||||
/// </summary>
|
||||
[DisplayName(DisplayNames.Timestamp)]
|
||||
[JsonPropertyName(DisplayNames.Timestamp)]
|
||||
public DateTime Timestamp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the environment.
|
||||
/// </summary>
|
||||
/// <example>Development</example>
|
||||
[DisplayName(DisplayNames.Environment)]
|
||||
[JsonPropertyName(DisplayNames.Environment)]
|
||||
public string? Environment { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the target.
|
||||
/// </summary>
|
||||
[DisplayName(DisplayNames.Target)]
|
||||
[JsonPropertyName(DisplayNames.Target)]
|
||||
public LogTarget? Target { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the x-forwarded-for header.
|
||||
/// </summary>
|
||||
/// <example>localhost</example>
|
||||
[DisplayName(DisplayNames.XForwardedFor)]
|
||||
[JsonPropertyName(DisplayNames.XForwardedFor)]
|
||||
public string? XForwardedFor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the service identifier.
|
||||
/// </summary>
|
||||
/// <example><see cref="Guid.NewGuid()"/></example>
|
||||
[DisplayName(DisplayNames.ServiceId)]
|
||||
[JsonPropertyName(DisplayNames.ServiceId)]
|
||||
public string? ServiceId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the request identifier.
|
||||
/// </summary>
|
||||
/// <example><see cref="Guid.NewGuid()"/></example>
|
||||
[DisplayName(DisplayNames.RequestId)]
|
||||
[JsonPropertyName(DisplayNames.RequestId)]
|
||||
public string? RequestId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the keyVaultProvider identifier.
|
||||
/// </summary>
|
||||
/// <example><see cref="Guid.NewGuid()"/></example>
|
||||
[DisplayName(DisplayNames.ClientId)]
|
||||
[JsonPropertyName(DisplayNames.ClientId)]
|
||||
public string? ClientId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the keyVaultProvider identifier.
|
||||
/// </summary>
|
||||
/// <example>keyVaultProviderRequest</example>
|
||||
[DisplayName(DisplayNames.Operation)]
|
||||
[JsonPropertyName(DisplayNames.Operation)]
|
||||
public LogOperation Operation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the user name.
|
||||
/// </summary>
|
||||
/// <example>keyVaultProviderRequest</example>
|
||||
[DisplayName(DisplayNames.User)]
|
||||
[JsonPropertyName(DisplayNames.User)]
|
||||
public string? User { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets user's email.
|
||||
/// </summary>
|
||||
/// <example>keyVaultProviderRequest</example>
|
||||
[DisplayName(DisplayNames.Email)]
|
||||
[JsonPropertyName(DisplayNames.Email)]
|
||||
public string? Email { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the user identifier.
|
||||
/// </summary>
|
||||
/// <example>keyVaultProviderRequest</example>
|
||||
[DisplayName(DisplayNames.UserId)]
|
||||
[JsonPropertyName(DisplayNames.UserId)]
|
||||
public string? UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the message.
|
||||
/// </summary>
|
||||
/// <example>A custom log message.</example>
|
||||
[DisplayName(DisplayNames.Message)]
|
||||
[JsonPropertyName(DisplayNames.Message)]
|
||||
public TMessage? Message { get; set; }
|
||||
}
|
||||
}
|
||||
55
Core.Blueprint.Logging/Adapters/LogOperation.cs
Normal file
55
Core.Blueprint.Logging/Adapters/LogOperation.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
// ***********************************************************************
|
||||
// <copyright file="LogOperation.cs">
|
||||
// Heath
|
||||
// </copyright>
|
||||
// ***********************************************************************
|
||||
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Core.Blueprint.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents all possible values for log operation.
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
public enum LogOperation
|
||||
{
|
||||
/// <summary>
|
||||
/// The keyVaultProvider request log operation type.
|
||||
/// </summary>
|
||||
[EnumMember(Value = DisplayNames.ClientRequest)]
|
||||
[JsonPropertyName(DisplayNames.ClientRequest)]
|
||||
ClientRequest = 0,
|
||||
|
||||
/// <summary>
|
||||
/// The keyVaultProvider response log operation type.
|
||||
/// </summary>
|
||||
[EnumMember(Value = DisplayNames.ClientResponse)]
|
||||
ClientResponse = 1,
|
||||
|
||||
/// <summary>
|
||||
/// The external request log operation type.
|
||||
/// </summary>
|
||||
[EnumMember(Value = DisplayNames.ExternalRequest)]
|
||||
ExternalRequest = 2,
|
||||
|
||||
/// <summary>
|
||||
/// The external response log operation type.
|
||||
/// </summary>
|
||||
[EnumMember(Value = DisplayNames.ExternalResponse)]
|
||||
ExternalResponse = 3,
|
||||
|
||||
/// <summary>
|
||||
/// The error log operation type.
|
||||
/// </summary>
|
||||
[EnumMember(Value = DisplayNames.Error)]
|
||||
Error = 4,
|
||||
|
||||
/// <summary>
|
||||
/// The info log operation type.
|
||||
/// </summary>
|
||||
[EnumMember(Value = DisplayNames.Info)]
|
||||
Info = 5,
|
||||
}
|
||||
}
|
||||
41
Core.Blueprint.Logging/Adapters/LogSeverity.cs
Normal file
41
Core.Blueprint.Logging/Adapters/LogSeverity.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
// ***********************************************************************
|
||||
// <copyright file="LogSeverity.cs">
|
||||
// Heath
|
||||
// </copyright>
|
||||
// ***********************************************************************
|
||||
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Core.Blueprint.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents all possible values for log severity.
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
public enum LogSeverity
|
||||
{
|
||||
/// <summary>
|
||||
/// The information severity level.
|
||||
/// </summary>
|
||||
[EnumMember(Value = DisplayNames.Information)]
|
||||
Info = 0,
|
||||
|
||||
/// <summary>
|
||||
/// The warning severity level.
|
||||
/// </summary>
|
||||
[EnumMember(Value = DisplayNames.Warning)]
|
||||
Warn = 1,
|
||||
|
||||
/// <summary>
|
||||
/// The error severity level.
|
||||
/// </summary>
|
||||
[EnumMember(Value = DisplayNames.Error)]
|
||||
Error = 2,
|
||||
|
||||
/// <summary>
|
||||
/// The fatal severity level.
|
||||
/// </summary>
|
||||
[EnumMember(Value = DisplayNames.Fatal)]
|
||||
Fatal = 3,
|
||||
}
|
||||
}
|
||||
41
Core.Blueprint.Logging/Adapters/LogTarget.cs
Normal file
41
Core.Blueprint.Logging/Adapters/LogTarget.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
// ***********************************************************************
|
||||
// <copyright file="LogTarget.cs">
|
||||
// Heath
|
||||
// </copyright>
|
||||
// ***********************************************************************
|
||||
|
||||
using System.ComponentModel;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Core.Blueprint.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// The service logger target object.
|
||||
/// </summary>
|
||||
public class LogTarget
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the log target method.
|
||||
/// </summary>
|
||||
/// <example>GET</example>
|
||||
[DisplayName(DisplayNames.Method)]
|
||||
[JsonPropertyName(DisplayNames.Method)]
|
||||
public string? Method { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the log target host.
|
||||
/// </summary>
|
||||
/// <example>GET</example>
|
||||
[DisplayName(DisplayNames.Host)]
|
||||
[JsonPropertyName(DisplayNames.Host)]
|
||||
public string? Host { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the log target route.
|
||||
/// </summary>
|
||||
/// <example>GET</example>
|
||||
[DisplayName(DisplayNames.Route)]
|
||||
[JsonPropertyName(DisplayNames.Route)]
|
||||
public string? Route { get; set; }
|
||||
}
|
||||
}
|
||||
20
Core.Blueprint.Logging/Adapters/ServiceSettings.cs
Normal file
20
Core.Blueprint.Logging/Adapters/ServiceSettings.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
// ***********************************************************************
|
||||
// <copyright file="ServiceSettings.cs">
|
||||
// Heath
|
||||
// </copyright>
|
||||
// ***********************************************************************
|
||||
|
||||
namespace Core.Blueprint.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// The service settings.
|
||||
/// </summary>
|
||||
public class ServiceSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the service identifier.
|
||||
/// </summary>
|
||||
public string? ApplicationName { get; set; }
|
||||
public string? LayerName { get; set; }
|
||||
}
|
||||
}
|
||||
70
Core.Blueprint.Logging/Configuration/Registerblueprint.cs
Normal file
70
Core.Blueprint.Logging/Configuration/Registerblueprint.cs
Normal file
@@ -0,0 +1,70 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Serilog;
|
||||
using Serilog.Events;
|
||||
|
||||
namespace Core.Blueprint.Logging.Configuration
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides extension methods for configuring logging in the application.
|
||||
/// </summary>
|
||||
public static class Registerblueprint
|
||||
{
|
||||
/// <summary>
|
||||
/// Registers logging services in the application.
|
||||
/// </summary>
|
||||
/// <param name="services">The <see cref="IServiceCollection"/> to add the services to.</param>
|
||||
/// <param name="builder">The <see cref="WebApplicationBuilder"/> for accessing configuration and application setup.</param>
|
||||
/// <returns>The updated <see cref="IServiceCollection"/>.</returns>
|
||||
public static IServiceCollection AddLogs(this IServiceCollection services, WebApplicationBuilder builder)
|
||||
{
|
||||
Log.Logger = new LoggerConfiguration()
|
||||
.WriteTo.Console(restrictedToMinimumLevel: LogEventLevel.Information)
|
||||
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
|
||||
.CreateLogger();
|
||||
|
||||
builder.Host.UseSerilog(Log.Logger);
|
||||
|
||||
services.AddScoped<ILoggerProvider, LoggerProvider>();
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures middleware for logging and error handling in the application.
|
||||
/// </summary>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> used to configure the middleware pipeline.</param>
|
||||
/// <param name="serviceSettings">The service settings required by the middleware.</param>
|
||||
public static void UseLogging(this IApplicationBuilder app, IConfiguration configuration)
|
||||
{
|
||||
var serviceSettings = new ServiceSettings();
|
||||
configuration.GetSection(nameof(ServiceSettings)).Bind(serviceSettings);
|
||||
|
||||
app.UseCustomHttpLogging(serviceSettings);
|
||||
app.UseHttpExceptionHandler(serviceSettings);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds middleware to handle HTTP exceptions globally.
|
||||
/// </summary>
|
||||
/// <param name="builder">The <see cref="IApplicationBuilder"/> to add the middleware to.</param>
|
||||
/// <param name="settings">The settings used by the exception handler middleware.</param>
|
||||
/// <returns>The updated <see cref="IApplicationBuilder"/>.</returns>
|
||||
public static IApplicationBuilder UseHttpExceptionHandler(this IApplicationBuilder builder, ServiceSettings settings)
|
||||
{
|
||||
return builder.UseMiddleware<HttpErrorMiddleware>(settings);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds custom HTTP logging middleware to the application pipeline.
|
||||
/// </summary>
|
||||
/// <param name="builder">The <see cref="IApplicationBuilder"/> to add the middleware to.</param>
|
||||
/// <param name="settings">The settings used by the logging middleware.</param>
|
||||
/// <returns>The updated <see cref="IApplicationBuilder"/>.</returns>
|
||||
public static IApplicationBuilder UseCustomHttpLogging(this IApplicationBuilder builder, ServiceSettings settings)
|
||||
{
|
||||
return builder.UseMiddleware<HttpLoggingMiddleware>(settings);
|
||||
}
|
||||
}
|
||||
}
|
||||
48
Core.Blueprint.Logging/Constants/Claims.cs
Normal file
48
Core.Blueprint.Logging/Constants/Claims.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
// ***********************************************************************
|
||||
// <copyright file="Claims.cs">
|
||||
// Heath
|
||||
// </copyright>
|
||||
// ***********************************************************************
|
||||
namespace Core.Blueprint.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// Constants for claims used in JWT tokens.
|
||||
/// </summary>
|
||||
public class Claims
|
||||
{
|
||||
/// <summary>
|
||||
/// Claim name for user's name.
|
||||
/// </summary>
|
||||
public const string Name = "name";
|
||||
|
||||
/// <summary>
|
||||
/// Claim name for user's name.
|
||||
/// </summary>
|
||||
public const string Email = "email";
|
||||
|
||||
/// <summary>
|
||||
/// Claim name for user's ID.
|
||||
/// </summary>
|
||||
public const string Id = "id";
|
||||
|
||||
/// <summary>
|
||||
/// Claim name for user's role ID.
|
||||
/// </summary>
|
||||
public const string Rol = "rol";
|
||||
|
||||
/// <summary>
|
||||
/// Claim name for user's companies.
|
||||
/// </summary>
|
||||
public const string Companies = "companies";
|
||||
|
||||
/// <summary>
|
||||
/// Claim name for user's projects.
|
||||
/// </summary>
|
||||
public const string Projects = "projects";
|
||||
|
||||
/// <summary>
|
||||
/// Claim name for user's surveys.
|
||||
/// </summary>
|
||||
public const string Surveys = "surveys";
|
||||
}
|
||||
}
|
||||
397
Core.Blueprint.Logging/Constants/DisplayNames.cs
Normal file
397
Core.Blueprint.Logging/Constants/DisplayNames.cs
Normal file
@@ -0,0 +1,397 @@
|
||||
// ***********************************************************************
|
||||
// <copyright file="DisplayNames.cs">
|
||||
// Heath
|
||||
// </copyright>
|
||||
// ***********************************************************************
|
||||
|
||||
namespace Core.Blueprint.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// Constants of the display names for this service.
|
||||
/// </summary>
|
||||
public static class DisplayNames
|
||||
{
|
||||
/// <summary>
|
||||
/// The active patameter.
|
||||
/// </summary>
|
||||
public const string Active = "active";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The keyVaultProvider identifier parameter.
|
||||
/// </summary>
|
||||
public const string ClientId = "keyVaultProviderId";
|
||||
|
||||
/// <summary>
|
||||
/// The keyVaultProvider request parameter.
|
||||
/// </summary>
|
||||
public const string ClientRequest = "keyVaultProviderRequest";
|
||||
|
||||
/// <summary>
|
||||
/// The keyVaultProvider response parameter.
|
||||
/// </summary>
|
||||
public const string ClientResponse = "keyVaultProviderResponse";
|
||||
|
||||
/// <summary>
|
||||
/// The creation date.
|
||||
/// </summary>
|
||||
public const string CreationDate = "creationDate";
|
||||
|
||||
/// <summary>
|
||||
/// The content parameter.
|
||||
/// </summary>
|
||||
public const string Content = "content";
|
||||
|
||||
/// <summary>
|
||||
/// The delete parameter.
|
||||
/// </summary>
|
||||
public const string Delete = "delete";
|
||||
|
||||
/// <summary>
|
||||
/// The description parameter.
|
||||
/// </summary>
|
||||
public const string Description = "description";
|
||||
|
||||
/// <summary>
|
||||
/// The detail parameter.
|
||||
/// </summary>
|
||||
public const string Detail = "detail";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The environment parameter.
|
||||
/// </summary>
|
||||
public const string Environment = "environment";
|
||||
|
||||
/// <summary>
|
||||
/// The error log severity level parameter.
|
||||
/// </summary>
|
||||
public const string Error = "error";
|
||||
|
||||
/// <summary>
|
||||
/// The error code parameter.
|
||||
/// </summary>
|
||||
public const string ErrorCode = "errorCode";
|
||||
|
||||
/// <summary>
|
||||
/// The external request parameter.
|
||||
/// </summary>
|
||||
public const string ExternalRequest = "externalRequest";
|
||||
|
||||
/// <summary>
|
||||
/// The external response parameter.
|
||||
/// </summary>
|
||||
public const string ExternalResponse = "externalResponse";
|
||||
|
||||
/// <summary>
|
||||
/// The fatal log severity level parameter.
|
||||
/// </summary>
|
||||
public const string Fatal = "fatal";
|
||||
|
||||
/// <summary>
|
||||
/// The host parameter.
|
||||
/// </summary>
|
||||
public const string Host = "host";
|
||||
|
||||
/// <summary>
|
||||
/// The identifier parameter.
|
||||
/// </summary>
|
||||
public const string Id = "id";
|
||||
|
||||
/// <summary>
|
||||
/// The inactive parameter.
|
||||
/// </summary>
|
||||
public const string Inactive = "inactive";
|
||||
|
||||
/// <summary>
|
||||
/// The info log severity level parameter.
|
||||
/// </summary>
|
||||
public const string Info = "info";
|
||||
|
||||
/// <summary>
|
||||
/// The information log severity level parameter.
|
||||
/// </summary>
|
||||
public const string Information = "information";
|
||||
|
||||
/// <summary>
|
||||
/// The media parameter.
|
||||
/// </summary>
|
||||
public const string Media = "media";
|
||||
|
||||
/// <summary>
|
||||
/// The media type parameter.
|
||||
/// </summary>
|
||||
public const string MediaType = "mediaType";
|
||||
|
||||
/// <summary>
|
||||
/// The media use type parameter.
|
||||
/// </summary>
|
||||
public const string MediaUseType = "mediaUseType";
|
||||
|
||||
/// <summary>
|
||||
/// Th message parameter.
|
||||
/// </summary>
|
||||
public const string Message = "message";
|
||||
|
||||
/// <summary>
|
||||
/// The method parameter.
|
||||
/// </summary>
|
||||
public const string Method = "method";
|
||||
|
||||
/// <summary>
|
||||
/// The monday parameter.
|
||||
/// </summary>
|
||||
public const string Monday = "monday";
|
||||
|
||||
/// <summary>
|
||||
/// The MXN parameter.
|
||||
/// </summary>
|
||||
public const string MXN = "MXN";
|
||||
|
||||
/// <summary>
|
||||
/// The name parameter.
|
||||
/// </summary>
|
||||
public const string Name = "name";
|
||||
|
||||
/// <summary>
|
||||
/// The next page parameter.
|
||||
/// </summary>
|
||||
public const string NextPage = "nextPage";
|
||||
|
||||
/// <summary>
|
||||
/// The nick name parameter.
|
||||
/// </summary>
|
||||
public const string NickName = "nickName";
|
||||
|
||||
/// <summary>
|
||||
/// The note parameter.
|
||||
/// </summary>
|
||||
public const string Note = "note";
|
||||
|
||||
/// <summary>
|
||||
/// The not so affordable parameter.
|
||||
/// </summary>
|
||||
public const string NotSoAffordable = "notSoAffordable";
|
||||
|
||||
/// <summary>
|
||||
/// The object status parameter.
|
||||
/// </summary>
|
||||
public const string ObjectStatus = "objectStatus";
|
||||
|
||||
/// <summary>
|
||||
/// The opening time parameter.
|
||||
/// </summary>
|
||||
public const string OpeningTime = "openingTime";
|
||||
|
||||
/// <summary>
|
||||
/// The operation days parameter.
|
||||
/// </summary>
|
||||
public const string OperationDays = "operationDays";
|
||||
|
||||
/// <summary>
|
||||
/// The page parameter.
|
||||
/// </summary>
|
||||
public const string Page = "page";
|
||||
|
||||
/// <summary>
|
||||
/// The page count parameter.
|
||||
/// </summary>
|
||||
public const string PageCount = "pageCount";
|
||||
|
||||
/// <summary>
|
||||
/// The page metadata parameter.
|
||||
/// </summary>
|
||||
public const string PageMetadata = "pageMetadata";
|
||||
|
||||
/// <summary>
|
||||
/// The page size parameter.
|
||||
/// </summary>
|
||||
public const string PageSize = "pageSize";
|
||||
|
||||
/// <summary>
|
||||
/// The parent identifier parameter.
|
||||
/// </summary>
|
||||
public const string ParentId = "ParentId";
|
||||
|
||||
/// <summary>
|
||||
/// The pet ticket price parameter.
|
||||
/// </summary>
|
||||
public const string PetTicketPrice = "petTicketPrice";
|
||||
|
||||
/// <summary>
|
||||
/// The place parameter.
|
||||
/// </summary>
|
||||
public const string Place = "place";
|
||||
|
||||
/// <summary>
|
||||
/// The place type parameter.
|
||||
/// </summary>
|
||||
public const string PlaceType = "placeType";
|
||||
|
||||
/// <summary>
|
||||
/// The previous page parameter.
|
||||
/// </summary>
|
||||
public const string PreviousPage = "previousPage";
|
||||
|
||||
/// <summary>
|
||||
/// The provider identifier parameter.
|
||||
/// </summary>
|
||||
public const string ProviderId = "providerId";
|
||||
|
||||
/// <summary>
|
||||
/// The provider type identifier parameter.
|
||||
/// </summary>
|
||||
public const string ProviderTypeId = "providerTypeId";
|
||||
|
||||
/// <summary>
|
||||
/// The request identifier parameter.
|
||||
/// </summary>
|
||||
public const string RequestId = "requestId";
|
||||
|
||||
/// <summary>
|
||||
/// The RNT identifier parameter.
|
||||
/// </summary>
|
||||
public const string RntId = "rntId";
|
||||
|
||||
/// <summary>
|
||||
/// The route parameter.
|
||||
/// </summary>
|
||||
public const string Route = "route";
|
||||
|
||||
/// <summary>
|
||||
/// The operation parameter.
|
||||
/// </summary>
|
||||
public const string Operation = "operation";
|
||||
|
||||
/// <summary>
|
||||
/// The other ticket price parameter.
|
||||
/// </summary>
|
||||
public const string OtherTicketPrice = "otherTicketPrice";
|
||||
|
||||
/// <summary>
|
||||
/// The path parameter.
|
||||
/// </summary>
|
||||
public const string Path = "path";
|
||||
|
||||
/// <summary>
|
||||
/// The saturday parameter.
|
||||
/// </summary>
|
||||
public const string Saturday = "saturday";
|
||||
|
||||
/// <summary>
|
||||
/// The secondary parameter.
|
||||
/// </summary>
|
||||
public const string Secondary = "secondary";
|
||||
|
||||
/// <summary>
|
||||
/// The service health parameter.
|
||||
/// </summary>
|
||||
public const string ServiceHealth = "serviceHealth";
|
||||
|
||||
/// <summary>
|
||||
/// The service identifier parameter.
|
||||
/// </summary>
|
||||
public const string ServiceId = "serviceId";
|
||||
|
||||
/// <summary>
|
||||
/// The severity parameter.
|
||||
/// </summary>
|
||||
public const string Severity = "severity";
|
||||
|
||||
/// <summary>
|
||||
/// The state identifier parameter.
|
||||
/// </summary>
|
||||
public const string StateId = "stateId";
|
||||
|
||||
/// <summary>
|
||||
/// The region identifier parameter.
|
||||
/// </summary>
|
||||
public const string StateProvinceRegionId = "regionId";
|
||||
|
||||
/// <summary>
|
||||
/// The sunday parameter.
|
||||
/// </summary>
|
||||
public const string Sunday = "sunday";
|
||||
|
||||
/// <summary>
|
||||
/// The tax identifier parameter.
|
||||
/// </summary>
|
||||
public const string TaxId = "taxId";
|
||||
|
||||
/// <summary>
|
||||
/// The target parameter.
|
||||
/// </summary>
|
||||
public const string Target = "target";
|
||||
|
||||
/// <summary>
|
||||
/// The thursday parameter.
|
||||
/// </summary>
|
||||
public const string Thursday = "thursday";
|
||||
|
||||
/// <summary>
|
||||
/// The timestamp parameter.
|
||||
/// </summary>
|
||||
public const string Timestamp = "timestamp";
|
||||
|
||||
/// <summary>
|
||||
/// The total items parameter.
|
||||
/// </summary>
|
||||
public const string TotalItems = "totalItems";
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the transaction identifier parameter.
|
||||
/// </summary>
|
||||
public const string TransactionId = "transactionId";
|
||||
|
||||
/// <summary>
|
||||
/// The tuesday parameter.
|
||||
/// </summary>
|
||||
public const string Tuesday = "tuesday";
|
||||
|
||||
/// <summary>
|
||||
/// The URI parameter.
|
||||
/// </summary>
|
||||
public const string Uri = "uri";
|
||||
|
||||
/// <summary>
|
||||
/// The update parameter.
|
||||
/// </summary>
|
||||
public const string Update = "update";
|
||||
|
||||
/// <summary>
|
||||
/// The x-forwarded-for header parameter.
|
||||
/// </summary>
|
||||
public const string XForwardedFor = "xForwardedFor";
|
||||
|
||||
/// <summary>
|
||||
/// The x-forwarded-for header parameter.
|
||||
/// </summary>
|
||||
public const string XForwardedForHeader = "X-Forwarded-For";
|
||||
|
||||
/// <summary>
|
||||
/// The final currency identifier parameter.
|
||||
/// </summary>
|
||||
public const string CurrencyId = "currencyId";
|
||||
|
||||
/// <summary>
|
||||
/// The user identifier parameter.
|
||||
/// </summary>
|
||||
public const string UserId = "userId";
|
||||
|
||||
/// <summary>
|
||||
/// The user parameter.
|
||||
/// </summary>
|
||||
public const string User = "user";
|
||||
|
||||
/// <summary>
|
||||
/// The warning log severity level.
|
||||
/// </summary>
|
||||
public const string Warning = "warning";
|
||||
|
||||
/// <summary>
|
||||
/// The email parameter.
|
||||
/// </summary>
|
||||
public const string Email = "email";
|
||||
|
||||
}
|
||||
}
|
||||
21
Core.Blueprint.Logging/Constants/EnvironmentVariables.cs
Normal file
21
Core.Blueprint.Logging/Constants/EnvironmentVariables.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
// ***********************************************************************
|
||||
// <copyright file="EnvironmentVariables.cs">
|
||||
// Heath
|
||||
// </copyright>
|
||||
// ***********************************************************************
|
||||
|
||||
namespace Core.Blueprint.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// Constants of the environment variables for this service.
|
||||
/// </summary>
|
||||
public static class EnvironmentVariables
|
||||
{
|
||||
/// <summary>
|
||||
/// The stage environment vriable.
|
||||
/// </summary>
|
||||
public const string Stage = "ASPNETCORE_ENVIRONMENT";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
79
Core.Blueprint.Logging/Constants/ErrorCodes.cs
Normal file
79
Core.Blueprint.Logging/Constants/ErrorCodes.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
// ***********************************************************************
|
||||
// <copyright file="ErrorCodes.cs">
|
||||
// Heath
|
||||
// </copyright>
|
||||
// ***********************************************************************
|
||||
|
||||
namespace Core.Blueprint.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// Constants for the error codes.
|
||||
/// </summary>
|
||||
public static class ErrorCodes
|
||||
{
|
||||
/// <summary>
|
||||
/// The generic entities not found error code.
|
||||
/// </summary>
|
||||
public const string EntitiesNotFound = "{0}EntitiesNotFound";
|
||||
|
||||
/// <summary>
|
||||
/// The entity already exsits error message.
|
||||
/// </summary>
|
||||
public const string EntityAlreadyExists = "{0}EntityAlreadyExists";
|
||||
|
||||
/// <summary>
|
||||
/// The generic entity not found error code.
|
||||
/// </summary>
|
||||
public const string EntityNotFound = "{0}EntityNotFound";
|
||||
|
||||
/// <summary>
|
||||
/// The generic not supported error code.
|
||||
/// </summary>
|
||||
public const string EntityNotSupported = "{0}NotSupported";
|
||||
|
||||
/// <summary>
|
||||
/// The internal server error code.
|
||||
/// </summary>
|
||||
public const string InternalServerError = "InternalServerError";
|
||||
|
||||
/// <summary>
|
||||
/// The invalid parameters in mapper error code.
|
||||
/// </summary>
|
||||
public const string InvalidParametersMapper = "InvalidParametersMapper";
|
||||
|
||||
/// <summary>
|
||||
/// The page size invalid value error code.
|
||||
/// </summary>
|
||||
public const string PageSizeInvalidValue = "PageSizeInvalidValue";
|
||||
|
||||
/// <summary>
|
||||
/// The page ot of range error code.
|
||||
/// </summary>
|
||||
public const string PageOutOfRange = "PageOutOfRange";
|
||||
|
||||
/// <summary>
|
||||
/// The property does not match the regular expresion error code.
|
||||
/// </summary>
|
||||
public const string PropertyDoesNotMatchRegex = "{0}PropertyDoesNotMatchRegex";
|
||||
|
||||
/// <summary>
|
||||
/// The property is required error code.
|
||||
/// </summary>
|
||||
public const string PropertyIsRequired = "{0}PropertyIsRequired";
|
||||
|
||||
/// <summary>
|
||||
/// The property length invalid error code.
|
||||
/// </summary>
|
||||
public const string PropertyLengthInvalid = "{0}PropertyLengthInvalid";
|
||||
|
||||
/// <summary>
|
||||
/// The property must be in range error code.
|
||||
/// </summary>
|
||||
public const string PropertyMustBeInRange = "{0}PropertyMustBeInRange";
|
||||
|
||||
/// <summary>
|
||||
/// The route not found error code.
|
||||
/// </summary>
|
||||
public const string RouteNotFound = "RouteNotFound";
|
||||
}
|
||||
}
|
||||
10
Core.Blueprint.Logging/Constants/Headers.cs
Normal file
10
Core.Blueprint.Logging/Constants/Headers.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
namespace Core.Blueprint.Logging
|
||||
{
|
||||
public static class Headers
|
||||
{
|
||||
/// <summary>
|
||||
/// The authorization header.
|
||||
/// </summary>
|
||||
public const string Authorization = "Authorization";
|
||||
}
|
||||
}
|
||||
148
Core.Blueprint.Logging/Constants/MimeTypes.cs
Normal file
148
Core.Blueprint.Logging/Constants/MimeTypes.cs
Normal file
@@ -0,0 +1,148 @@
|
||||
// ***********************************************************************
|
||||
// <copyright file="MimeTypes.cs">
|
||||
// Heath
|
||||
// </copyright>
|
||||
// ***********************************************************************
|
||||
|
||||
using System.Globalization;
|
||||
|
||||
namespace Core.Blueprint.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// Constants for the mime types.
|
||||
/// </summary>
|
||||
public static class MimeTypes
|
||||
{
|
||||
/// <summary>
|
||||
/// The service application/json mime type.
|
||||
/// </summary>
|
||||
public const string ApplicationJson = "application/json";
|
||||
|
||||
/// <summary>
|
||||
/// The application/pdf mime type.
|
||||
/// </summary>
|
||||
public const string ApplicationPdf = "application/pdf";
|
||||
|
||||
/// <summary>
|
||||
/// The end index.
|
||||
/// </summary>
|
||||
public const int EndIndex = 5;
|
||||
|
||||
/// <summary>
|
||||
/// The JPEG extension.
|
||||
/// </summary>
|
||||
public const string ExtensionGif = "gif";
|
||||
|
||||
/// <summary>
|
||||
/// The JPEG extension.
|
||||
/// </summary>
|
||||
public const string ExtensionJpeg = "jpeg";
|
||||
|
||||
/// <summary>
|
||||
/// The PNG extension.
|
||||
/// </summary>
|
||||
public const string ExtensionPng = "png";
|
||||
|
||||
/// <summary>
|
||||
/// The SVG extension.
|
||||
/// </summary>
|
||||
public const string ExtensionSvg = "svg";
|
||||
|
||||
/// <summary>
|
||||
/// The image/gif mime type.
|
||||
/// </summary>
|
||||
public const string ImageGif = "image/gif";
|
||||
|
||||
/// <summary>
|
||||
/// The image/jpeg mime type.
|
||||
/// </summary>
|
||||
public const string ImageJpeg = "image/jpeg";
|
||||
|
||||
/// <summary>
|
||||
/// The image/png mime type.
|
||||
/// </summary>
|
||||
public const string ImagePng = "image/png";
|
||||
|
||||
/// <summary>
|
||||
/// The image/svg+xml mime type.
|
||||
/// </summary>
|
||||
public const string ImageSvg = "image/svg+xml";
|
||||
|
||||
/// <summary>
|
||||
/// The identifier GIF.
|
||||
/// </summary>
|
||||
public const string IdentifierGif = "R0LGO";
|
||||
|
||||
/// <summary>
|
||||
/// The identifier PNG.
|
||||
/// </summary>
|
||||
public const string IdentifierJpeg = "/9J/4";
|
||||
|
||||
/// <summary>
|
||||
/// The identifier PDF.
|
||||
/// </summary>
|
||||
public const string IdentifierPdf = "JVBER";
|
||||
|
||||
/// <summary>
|
||||
/// The identifier PNG.
|
||||
/// </summary>
|
||||
public const string IdentifierPng = "IVBOR";
|
||||
|
||||
/// <summary>
|
||||
/// The identifier SVG.
|
||||
/// </summary>
|
||||
public const string IdentifierSvg = "PHN2Z";
|
||||
|
||||
/// <summary>
|
||||
/// The parameter name.
|
||||
/// </summary>
|
||||
public const string ParameterName = "MimeType";
|
||||
|
||||
/// <summary>
|
||||
/// The start index.
|
||||
/// </summary>
|
||||
public const int StartIndex = 0;
|
||||
|
||||
/// <summary>
|
||||
/// The mime type dictionary.
|
||||
/// </summary>
|
||||
public static readonly Dictionary<string, string> Dictionary = new Dictionary<string, string>
|
||||
{
|
||||
{ IdentifierJpeg, ImageJpeg },
|
||||
{ IdentifierPng, ImagePng },
|
||||
{ IdentifierGif, ImageGif },
|
||||
{ IdentifierSvg, ImageSvg },
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// The mime type dictionary.
|
||||
/// </summary>
|
||||
public static readonly Dictionary<string, string> DictionaryExtension = new Dictionary<string, string>
|
||||
{
|
||||
{ IdentifierJpeg, ExtensionJpeg },
|
||||
{ IdentifierPng, ExtensionPng },
|
||||
{ IdentifierGif, ExtensionGif },
|
||||
{ IdentifierSvg, ExtensionSvg },
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Gets the mime type.
|
||||
/// </summary>
|
||||
/// <param name="content">The cpntent with mime type identifier, substring 0, 5 from content.</param>
|
||||
/// <returns>A <see cref="string"/> representing the value.</returns>
|
||||
public static string GetMimeType(this string content)
|
||||
{
|
||||
return Dictionary.FirstOrDefault(_ => _.Key == content[..EndIndex].ToUpper(CultureInfo.InvariantCulture)).Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the extension.
|
||||
/// </summary>
|
||||
/// <param name="content">The mime type identifier, substring 0, 5 from content.</param>
|
||||
/// <returns>A <see cref="string"/> representing the value.</returns>
|
||||
public static string GetExtension(this string content)
|
||||
{
|
||||
return DictionaryExtension.FirstOrDefault(_ => _.Key == content[..EndIndex].ToUpper(CultureInfo.InvariantCulture)).Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
29
Core.Blueprint.Logging/Constants/Responses.cs
Normal file
29
Core.Blueprint.Logging/Constants/Responses.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
// ***********************************************************************
|
||||
// <copyright file="Responses.cs">
|
||||
// Heath
|
||||
// </copyright>
|
||||
// ***********************************************************************
|
||||
|
||||
namespace Core.Blueprint.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// Constants of the responses for this service.
|
||||
/// </summary>
|
||||
public static class Responses
|
||||
{
|
||||
/// <summary>
|
||||
/// The health response.
|
||||
/// </summary>
|
||||
public const string HealthyService = "healthy";
|
||||
|
||||
/// <summary>
|
||||
/// The route does not exist response.
|
||||
/// </summary>
|
||||
public const string RouteDoesNotExist = "The specified route '{0}' does not exist for method '{1}' in this service.";
|
||||
|
||||
/// <summary>
|
||||
/// The target response.
|
||||
/// </summary>
|
||||
public const string Target = "{0}|{1}://{2}{3}";
|
||||
}
|
||||
}
|
||||
12
Core.Blueprint.Logging/Contracts/ILoggerProvider.cs
Normal file
12
Core.Blueprint.Logging/Contracts/ILoggerProvider.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace Core.Blueprint.Logging
|
||||
{
|
||||
public interface ILoggerProvider
|
||||
{
|
||||
public void LogInformation(string service, params object[] args);
|
||||
public void LogOperationStarted(string service, params object[] args);
|
||||
public void LogOperationFinished(string service, params object[] args);
|
||||
public void LogWarning(string message, params object[] args);
|
||||
public void LogError(string servicee, params object[] args);
|
||||
public void LogCritical(Exception exception, string message, params object[] args);
|
||||
}
|
||||
}
|
||||
21
Core.Blueprint.Logging/Core.Blueprint.Logging.csproj
Normal file
21
Core.Blueprint.Logging/Core.Blueprint.Logging.csproj
Normal file
@@ -0,0 +1,21 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<ItemGroup>
|
||||
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.0" />
|
||||
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="3.0.1" />
|
||||
<PackageReference Include="Serilog.Extensions.Hosting" Version="9.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
|
||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
92
Core.Blueprint.Logging/Middleware/HttpErrorMiddleware.cs
Normal file
92
Core.Blueprint.Logging/Middleware/HttpErrorMiddleware.cs
Normal file
@@ -0,0 +1,92 @@
|
||||
// ***********************************************************************
|
||||
// <copyright file="HttpErrorMiddleware.cs">
|
||||
// Heath
|
||||
// </copyright>
|
||||
// ***********************************************************************
|
||||
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Serilog;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Core.Blueprint.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// Handles HTTP logging.
|
||||
/// </summary>
|
||||
public class HttpErrorMiddleware
|
||||
{
|
||||
private readonly ILogger logger;
|
||||
private readonly RequestDelegate requestProcess;
|
||||
public readonly ServiceSettings settings;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instrance of <see cref="HttpErrorMiddleware"/>.
|
||||
/// </summary>
|
||||
/// <param name="logger">The logger representig an instance of <see cref="ILogger"/>.</param>
|
||||
/// <param name="requestProcess">The request delegate process.</param>
|
||||
public HttpErrorMiddleware(ILogger logger, RequestDelegate requestProcess, ServiceSettings settings)
|
||||
{
|
||||
this.logger = logger;
|
||||
this.requestProcess = requestProcess;
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoke method.
|
||||
/// </summary>
|
||||
/// <param name="context">The HTTP context.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
try
|
||||
{
|
||||
await requestProcess(context).ConfigureAwait(false);
|
||||
}
|
||||
catch (HttpException exception)
|
||||
{
|
||||
await HandleErrorResponse(
|
||||
context,
|
||||
exception.Message,
|
||||
exception.ErrorCode,
|
||||
exception.StatusCode).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception defaultException)
|
||||
{
|
||||
await HandleErrorResponse(
|
||||
context,
|
||||
defaultException.Message,
|
||||
ErrorCodes.InternalServerError,
|
||||
StatusCodes.Status500InternalServerError).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles error responses.
|
||||
/// </summary>
|
||||
/// <param name="context">The HTTP context.</param>
|
||||
/// <param name="message">The error message.</param>
|
||||
/// <param name="errorCode">The error code.</param>
|
||||
/// <param name="statusCode">The HTTP status code.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||
private async Task HandleErrorResponse(HttpContext context, string? message, string? errorCode, int statusCode)
|
||||
{
|
||||
var errorMessage = new HttpError(
|
||||
message,
|
||||
errorCode,
|
||||
string.Format(
|
||||
Responses.Target,
|
||||
context.Request.Method,
|
||||
context.Request.Scheme,
|
||||
context.Request.Host.Host,
|
||||
context.Request.Path));
|
||||
|
||||
logger.LogError<HttpError>(context, errorMessage, $"{settings.ApplicationName}-{settings.LayerName}");
|
||||
|
||||
context.Response.ContentType = MimeTypes.ApplicationJson;
|
||||
context.Response.StatusCode = statusCode;
|
||||
|
||||
await context.Response.WriteAsync(JsonSerializer.Serialize(errorMessage)).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
237
Core.Blueprint.Logging/Middleware/HttpLogger.cs
Normal file
237
Core.Blueprint.Logging/Middleware/HttpLogger.cs
Normal file
@@ -0,0 +1,237 @@
|
||||
// ***********************************************************************
|
||||
// <copyright file="HttpLogger.cs">
|
||||
// Heath
|
||||
// </copyright>
|
||||
// ***********************************************************************
|
||||
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.IO;
|
||||
using Serilog;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Core.Blueprint.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// Handles all logging scenarios.
|
||||
/// </summary>
|
||||
public static class HttpLogger
|
||||
{
|
||||
/// <summary>
|
||||
/// The JSON serializer options for logging methods.
|
||||
/// </summary>
|
||||
public static JsonSerializerOptions serializerOptions = new JsonSerializerOptions
|
||||
{
|
||||
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
|
||||
Converters = {
|
||||
new JsonStringEnumConverter( JsonNamingPolicy.CamelCase),
|
||||
},
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Logs an error message.
|
||||
/// </summary>
|
||||
/// <typeparam name="TMessage">The generic message parameter.</typeparam>
|
||||
/// <param name="context">The HTTP context.</param>
|
||||
/// <param name="message">The message.</param>
|
||||
/// <param name="serviceId">The service identifier.</param>
|
||||
public static void LogError<TMessage>(this ILogger logger, HttpContext context, TMessage message, string? serviceId)
|
||||
{
|
||||
var logMessage = CreateErrorLog(context, message, serviceId);
|
||||
logger.Error(logMessage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs an information message.
|
||||
/// </summary>
|
||||
/// <typeparam name="TMessage">The generic message parameter.</typeparam>
|
||||
/// <param name="context">The HTTP context.</param>
|
||||
/// <param name="message">The message.</param>
|
||||
/// <param name="serviceId">The service identifier.</param>
|
||||
public static void LogInfo<TMessage>(this ILogger logger, HttpContext context, TMessage message, string? serviceId)
|
||||
{
|
||||
var logMessage = CreateInfoLog(context, message, serviceId);
|
||||
logger.Information(logMessage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs an incoming HTTP request.
|
||||
/// </summary>
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <param name="context">The HTTP context.</param>
|
||||
/// <param name="recyclableMemoryStreamManager">The recyclable mmory stream manager.</param>
|
||||
/// <param name="serviceId">The service identifier.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||
public static async Task LogRequest(
|
||||
this ILogger logger,
|
||||
HttpContext context,
|
||||
RecyclableMemoryStreamManager recyclableMemoryStreamManager,
|
||||
string? serviceId)
|
||||
{
|
||||
context.Request.EnableBuffering();
|
||||
await using var requestStream = recyclableMemoryStreamManager.GetStream();
|
||||
await context.Request.Body.CopyToAsync(requestStream);
|
||||
|
||||
var logMessage = CreateRequestLog(
|
||||
context,
|
||||
ReadStream(requestStream),
|
||||
serviceId);
|
||||
logger.Information(logMessage);
|
||||
|
||||
context.Request.Body.Position = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs an outcome HTTP response.
|
||||
/// </summary>
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <param name="context">The HTTP context.</param>
|
||||
/// <param name="recyclableMemoryStreamManager">The recyclable mmory stream manager.</param>
|
||||
/// <param name="requestProcess">The request delegate process.</param>
|
||||
/// <param name="serviceId">The service identifier.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||
///
|
||||
public static async Task LogResponse(
|
||||
this ILogger logger,
|
||||
HttpContext context,
|
||||
RecyclableMemoryStreamManager recyclableMemoryStreamManager,
|
||||
RequestDelegate requestProcess,
|
||||
string? serviceId)
|
||||
{
|
||||
var originalBodyStream = context.Response.Body;
|
||||
await using var responseBody = recyclableMemoryStreamManager.GetStream();
|
||||
context.Response.Body = responseBody;
|
||||
|
||||
await requestProcess(context);
|
||||
|
||||
context.Response.Body.Seek(0, SeekOrigin.Begin);
|
||||
var text = await new StreamReader(context.Response.Body).ReadToEndAsync();
|
||||
context.Response.Body.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
var logMessage = CreateResponseLog(context, text, serviceId);
|
||||
logger.Information(logMessage);
|
||||
|
||||
await responseBody.CopyToAsync(originalBodyStream);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an error log.
|
||||
/// </summary>
|
||||
/// <typeparam name="TMessage">The generic message.</typeparam>
|
||||
/// <param name="context">The HTTP context.</param>
|
||||
/// <param name="message">The error message.</param>
|
||||
/// <param name="serviceId">The service identifier.</param>
|
||||
/// <returns>A <see cref="string"/> representig the error log.</returns>
|
||||
private static string CreateErrorLog<TMessage>(HttpContext context, TMessage message, string? serviceId)
|
||||
=> CreateLog(context, LogSeverity.Error, LogOperation.Error, message, serviceId);
|
||||
|
||||
/// <summary>
|
||||
/// Creates an info log.
|
||||
/// </summary>
|
||||
/// <typeparam name="TMessage">The generic message.</typeparam>
|
||||
/// <param name="context">The HTTP context.</param>
|
||||
/// <param name="message">The info message.</param>
|
||||
/// <param name="serviceId">The service identifier.</param>
|
||||
/// <returns>A <see cref="string"/> representig the info log.</returns>
|
||||
private static string CreateInfoLog<TMessage>(HttpContext context, TMessage message, string? serviceId)
|
||||
=> CreateLog(context, LogSeverity.Info, LogOperation.Info, message, serviceId);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a request log.
|
||||
/// </summary>
|
||||
/// <param name="context">The HTTP context.</param>
|
||||
/// <param name="requestBody">The request body.</param>
|
||||
/// <param name="serviceId">The service identifier.</param>
|
||||
/// <returns>A <see cref="string"/> representig the request log.</returns>
|
||||
private static string CreateRequestLog(HttpContext context, string? requestBody, string? serviceId)
|
||||
=> CreateLog(context, LogSeverity.Info, LogOperation.ClientRequest, requestBody, serviceId);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a response log.
|
||||
/// </summary>
|
||||
/// <param name="context">The HTTP context.</param>
|
||||
/// <param name="responseBody">The response body.</param>
|
||||
/// <param name="serviceId">The service identifier.</param>
|
||||
/// <returns>A <see cref="string"/> representig the response log.</returns>
|
||||
private static string CreateResponseLog(HttpContext context, string? responseBody, string? serviceId)
|
||||
=> CreateLog(context, LogSeverity.Info, LogOperation.ClientResponse, responseBody, serviceId);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a generic log.
|
||||
/// </summary>
|
||||
/// <param name="context">The HTTP context.</param>
|
||||
/// <param name="severity">The log severity.</param>
|
||||
/// <param name="operation">The log operation.</param>
|
||||
/// <param name="message">The log message</param>
|
||||
/// <param name="serviceId">The service identifier.</param>
|
||||
/// <returns>A <see cref="string"/> representing a generic log.</returns>
|
||||
private static string CreateLog<TMessage>(
|
||||
HttpContext context,
|
||||
LogSeverity severity,
|
||||
LogOperation operation,
|
||||
TMessage message,
|
||||
string? serviceId)
|
||||
{
|
||||
var tokenHeader = context.Request.Headers[Headers.Authorization].FirstOrDefault()?.Split(" ").Last();
|
||||
var tokenHandler = new JwtSecurityTokenHandler();
|
||||
var token = tokenHeader is not null ? tokenHandler.ReadJwtToken(tokenHeader) : null;
|
||||
|
||||
var log = new LogDetail<TMessage>
|
||||
{
|
||||
Severity = severity,
|
||||
Target = new LogTarget
|
||||
{
|
||||
Method = context.Request.Method,
|
||||
Host = context.Request.Host.Host,
|
||||
Route = context.Request.Path,
|
||||
},
|
||||
Email = token?.Claims.FirstOrDefault(c => c.Type == Claims.Email)?.Value,
|
||||
User = token?.Claims.FirstOrDefault(c => c.Type == Claims.Name)?.Value,
|
||||
UserId = token?.Claims.FirstOrDefault(c => c.Type == Claims.Id)?.Value,
|
||||
Environment = Environment.GetEnvironmentVariable(EnvironmentVariables.Stage),
|
||||
Operation = operation,
|
||||
RequestId = context.Request.Headers[DisplayNames.RequestId],
|
||||
ServiceId = serviceId,
|
||||
XForwardedFor = context.Request.Headers[DisplayNames.XForwardedForHeader],
|
||||
Timestamp = DateTime.Now,
|
||||
Message = message,
|
||||
};
|
||||
|
||||
var serializedLog = JsonSerializer.Serialize(log, serializerOptions);
|
||||
|
||||
return serializedLog
|
||||
.Replace("\\u0022", "\"")
|
||||
.Replace("\"{", "{")
|
||||
.Replace("}\"", "}")
|
||||
.Replace("\\u0027", "'")
|
||||
.Replace("\\\u0027", "'")
|
||||
.Replace("\n", "");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the stream.
|
||||
/// </summary>
|
||||
/// <param name="stream">The stream to be read.</param>
|
||||
/// <returns>A <see cref="string?"/> representig the request body.</returns>
|
||||
private static string? ReadStream(Stream stream)
|
||||
{
|
||||
const int readChunkBufferLength = 4096;
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
using var textWriter = new StringWriter();
|
||||
using var reader = new StreamReader(stream);
|
||||
var readChunk = new char[readChunkBufferLength];
|
||||
int readChunkLength;
|
||||
do
|
||||
{
|
||||
readChunkLength = reader.ReadBlock(readChunk, 0, readChunkBufferLength);
|
||||
textWriter.Write(readChunk, 0, readChunkLength);
|
||||
} while (readChunkLength > 0);
|
||||
|
||||
var stringItem = textWriter.ToString();
|
||||
|
||||
return stringItem != string.Empty ? stringItem : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
69
Core.Blueprint.Logging/Middleware/HttpLoggingMiddleware.cs
Normal file
69
Core.Blueprint.Logging/Middleware/HttpLoggingMiddleware.cs
Normal file
@@ -0,0 +1,69 @@
|
||||
// ***********************************************************************
|
||||
// <copyright file="HttpLoggingMiddleware.cs">
|
||||
// Heath
|
||||
// </copyright>
|
||||
// ***********************************************************************
|
||||
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.IO;
|
||||
using Serilog;
|
||||
|
||||
namespace Core.Blueprint.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// Handles HTTP logging.
|
||||
/// </summary>
|
||||
public class HttpLoggingMiddleware
|
||||
{
|
||||
private readonly ILogger logger;
|
||||
private readonly RequestDelegate requestProcess;
|
||||
private readonly ServiceSettings settings;
|
||||
private readonly RecyclableMemoryStreamManager recyclableMemoryStreamManager;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instrance of <see cref="HttpLoggingMiddleware"/>.
|
||||
/// </summary>
|
||||
/// <param name="requestProcess">The request delegate process.</param>
|
||||
/// <param name="logger">The logger representig an instance of <see cref="ILogger"/>.</param>
|
||||
/// <param name="settings">The service settings.</param>
|
||||
public HttpLoggingMiddleware(RequestDelegate requestProcess, ILogger logger, ServiceSettings settings)
|
||||
{
|
||||
this.logger = logger;
|
||||
this.requestProcess = requestProcess;
|
||||
this.settings = settings;
|
||||
recyclableMemoryStreamManager = new RecyclableMemoryStreamManager();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoke method.
|
||||
/// </summary>
|
||||
/// <param name="context">The HTTP context.</param>
|
||||
/// <returns></returns>
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
await LogRequest(context);
|
||||
await LogResponse(context);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs an incoming HTTP request.
|
||||
/// </summary>
|
||||
/// <param name="context">The HTTP context.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||
private async Task LogRequest(HttpContext context)
|
||||
{
|
||||
await logger.LogRequest(context, recyclableMemoryStreamManager, $"{settings.ApplicationName}-{settings.LayerName}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs an outcome HTTP response.
|
||||
/// </summary>
|
||||
/// <param name="context">The HTTP context.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||
private async Task LogResponse(HttpContext context)
|
||||
{
|
||||
await logger.LogResponse(context, recyclableMemoryStreamManager, requestProcess, $"{settings.ApplicationName}-{settings.LayerName}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
89
Core.Blueprint.Logging/Provider/LoggerProvider.cs
Normal file
89
Core.Blueprint.Logging/Provider/LoggerProvider.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
namespace Core.Blueprint.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides logging functionalities using Serilog.
|
||||
/// </summary>
|
||||
public class LoggerProvider : ILoggerProvider
|
||||
{
|
||||
private readonly Serilog.ILogger logger;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LoggerProvider"/> class.
|
||||
/// </summary>
|
||||
/// <param name="logger">The Serilog logger instance.</param>
|
||||
public LoggerProvider(Serilog.ILogger logger)
|
||||
{
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs an informational message for a specific service.
|
||||
/// </summary>
|
||||
/// <param name="service">The name of the service.</param>
|
||||
/// <param name="args">Additional arguments to include in the log.</param>
|
||||
public void LogInformation(string service, params object[] args)
|
||||
{
|
||||
logger.Information("Starting operation in {service} service", service, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs a message indicating the start of an operation in a specific service.
|
||||
/// </summary>
|
||||
/// <param name="service">The name of the service.</param>
|
||||
/// <param name="args">Additional parameters associated with the operation.</param>
|
||||
public void LogOperationStarted(string service, params object[] args)
|
||||
{
|
||||
logger.Information("Starting operation in {Service} service with parameters: {@Args}", service, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs a message indicating the completion of an operation in a specific service.
|
||||
/// </summary>
|
||||
/// <param name="service">The name of the service.</param>
|
||||
/// <param name="args">Additional parameters associated with the operation.</param>
|
||||
public void LogOperationFinished(string service, params object[] args)
|
||||
{
|
||||
logger.Information("Finishing operation in {Service} service with parameters: {@Args}", service, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs a general informational message.
|
||||
/// </summary>
|
||||
/// <param name="message">The message to log.</param>
|
||||
public void LogInformation(string message)
|
||||
{
|
||||
logger.Information(message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs a warning message with additional context.
|
||||
/// </summary>
|
||||
/// <param name="message">The warning message to log.</param>
|
||||
/// <param name="args">Additional arguments to include in the log.</param>
|
||||
public void LogWarning(string message, params object[] args)
|
||||
{
|
||||
logger.Warning(message, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs an error that occurred in a specific service.
|
||||
/// </summary>
|
||||
/// <param name="service">The name of the service.</param>
|
||||
/// <param name="args">Additional details about the error.</param>
|
||||
public void LogError(string service, params object[] args)
|
||||
{
|
||||
logger.Error("An error occurred in `{service}` Exception: {@Args}", service, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs a critical error with an exception, message, and additional context.
|
||||
/// </summary>
|
||||
/// <param name="exception">The exception associated with the critical error.</param>
|
||||
/// <param name="message">The critical error message.</param>
|
||||
/// <param name="args">Additional arguments to include in the log.</param>
|
||||
public void LogCritical(Exception exception, string message, params object[] args)
|
||||
{
|
||||
logger.Fatal(exception, message, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user