Leviasan.Sanlog.EntityFrameworkCore
1.1.3
dotnet add package Leviasan.Sanlog.EntityFrameworkCore --version 1.1.3
NuGet\Install-Package Leviasan.Sanlog.EntityFrameworkCore -Version 1.1.3
<PackageReference Include="Leviasan.Sanlog.EntityFrameworkCore" Version="1.1.3" />
<PackageVersion Include="Leviasan.Sanlog.EntityFrameworkCore" Version="1.1.3" />
<PackageReference Include="Leviasan.Sanlog.EntityFrameworkCore" />
paket add Leviasan.Sanlog.EntityFrameworkCore --version 1.1.3
#r "nuget: Leviasan.Sanlog.EntityFrameworkCore, 1.1.3"
#:package Leviasan.Sanlog.EntityFrameworkCore@1.1.3
#addin nuget:?package=Leviasan.Sanlog.EntityFrameworkCore&version=1.1.3
#tool nuget:?package=Leviasan.Sanlog.EntityFrameworkCore&version=1.1.3
Leviasan.Sanlog.EntityFrameworkCore
Represents the logger for the NET8.0+ apps. Provides API for using EntityFrameworkCore context as storage for saving log entries from different applications in one database scheme separated by application identifier.
Get started
Add a logger to pipeline
There are 2 extension methods to add a logger to service collection. The first approach writes an event to the database after it occurred.
public static ILoggingBuilder AddSanlogService(this ILoggingBuilder builder, ...)
This approach uses BackgroundService to write an event to the queue, that writes one to the database in another thread.
public static ILoggingBuilder AddHostedSanlogService(this ILoggingBuilder builder, ...)
Migration and implementation of the IDesignTimeDbContextFactory<SanlogDbContext>
Install an additional NuGet package Microsoft.EntityFrameworkCore.Tools.
To create a migration need to invoke Add-Migration InitialDatabase -Context SanlogDbContext. To apply need to invoke Update-Database -Context SanlogDbContext.
Simple implementation of the IDesignTimeDbContextFactory<SanlogDbContext> for a trivial app that uses Microsoft.EntityFrameworkCore.SqlServer as log entry storage.
internal sealed class SanlogDbContextDesignTimeDbContextFactory : IDesignTimeDbContextFactory<SanlogDbContext>
{
public SanlogDbContext CreateDbContext(string[] args)
{
var optionsBuilder = new DbContextOptionsBuilder<SanlogDbContext>();
// Here need Use* method of your database provider
var connectionString = "Server=(localdb)\\mssqllocaldb;Database=sanlogdb;Trusted_Connection=True";
optionsBuilder.UseSqlServer(connectionString, serverOptions =>
{
// [Required] Set migration assembly
serverOptions.MigrationsAssembly(typeof(SanlogDbContextDesignTimeDbContextFactory).Assembly.GetName().Name);
});
return new SanlogDbContext(optionsBuilder.Options);
}
}
Design-time service for an application that used many environments.
To create a migration need to invoke Add-Migration InitialDatabase -Args "appsettings.json LoggerConnection" -Context SanlogDbContext. To apply need to invoke Update-Database -Args "appsettings.json LoggerConnection" -Context SanlogDbContext.
internal sealed class SanlogDbContextDesignTimeDbContextFactory : IDesignTimeDbContextFactory<SanlogDbContext>
{
public SanlogDbContext CreateDbContext(string[] args)
{
if (args.Length != 2)
throw new InvalidOperationException("Invalid arguments count");
var configurationBuilder = new ConfigurationBuilder();
configurationBuilder.SetBasePath(AppDomain.CurrentDomain.BaseDirectory);
configurationBuilder.AddJsonFile(args[0]);
var configuration = configurationBuilder.Build()!;
var optionsBuilder = new DbContextOptionsBuilder<SanlogDbContext>();
var connectionString = configuration.GetConnectionString(args[1]);
optionsBuilder.UseSqlServer(connectionString, serverOptions => // Here need Use* method of your database provider
{
// [Required] Set migration assembly
serverOptions.MigrationsAssembly(typeof(SanlogDbContextDesignTimeDbContextFactory).Assembly.GetName().Name);
});
return new SanlogDbContext(optionsBuilder.Options);
}
}
Registers your application
You must connect to your database provider and invoke the insert command to the LogApps table. For example for MSSQL: insert into dbo.LogApps values ('e6bcc7df-e201-4d0b-02a3-08dbd09ffc89', 'ConsoleApp', 'Development').
Logging in a trivial app
This first example shows the basics, but it is only suitable for a trivial console app. In the next section, you see how to improve the code by considering scale, performance, configuration, and typical programming patterns.
Example for database provider: Microsoft.EntityFrameworkCore.SqlServer.
internal sealed partial class Program
{
private static void Main(string[] args)
{
using ILoggerFactory factory = LoggerFactory.Create(builder => builder.AddSanlogService(
contextConfigure =>
{
// Configure your database provider
var connectionString = "Server=(localdb)\\mssqllocaldb;Database=sanlogdb;Trusted_Connection=True";
contextConfigure.UseSqlServer(connectionString);
},
loggingConfigure =>
{
// [Required] Here need to insert your specific application identifier
loggingConfigure.AppId = Guid.Parse("e6bcc7df-e201-4d0b-02a3-08dbd09ffc89");
}));
ILogger logger = factory.CreateLogger(nameof(Program));
LogInvokedMethod(logger, null, nameof(Program), nameof(Main));
Console.WriteLine("Finished");
}
[LoggerMessage(Level = LogLevel.Information, Message = "ClassName: {ClassName}. Method: {MethodName}")]
static partial void LogInvokedMethod(ILogger logger, Exception? exception, string className, string methodName);
}
The preceding example:
- Creates an
ILoggerFactory. TheILoggerFactorystores all the configuration and determines where log messages are sent. - Creates an
ILoggerwith a category named "Program". The category is a string associated with each message logged by theILoggerobject. It's used to group log messages from the same class (or category) together while searching or filtering logs. - Calls
LogInvokedMethodto log a message at the Information level. The log level indicates the logged event's severity and filters out less important log messages. The log entry also includes a message template "ClassName: {ClassName}. Method: {MethodName}" and a key-value pairs ClassName = Program and MethodName = Main. The key name (or placeholder) comes from the word inside the curly braces in the template and the value comes from the remaining method argument. Logging compile-time source generation is usually a better alternative toILoggerextension methods likeLogInformation. Logging source generation offers better performance, and stronger typing, and avoids spreading string constants throughout your methods. The tradeoff is that using this technique requires a bit more code.
Integration with hosts and dependency injection
If your application uses Dependency Injection (DI) or a host such as ASP.NET's WebApplication or Generic Host then you should use ILoggerFactory and ILogger objects from the DI container rather than creating them directly. Host builders initialize the default configuration, then add a configured ILoggerFactory object to the host's DI container when the host is built. Before the host is built you can adjust the logging configuration via HostApplicationBuilder.Logging, WebApplicationBuilder.Logging, or similar APIs on other hosts. Hosts also apply logging configuration from default configuration sources such as appsettings.json and environment variables. For more information, see Configuration in .NET.
internal sealed class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
/* ... Another configuration ... */
builder.AddHostedSanlogService(contextConfigure =>
{
// Configure your database provider
var connectionString = builder.Configuration.GetConnectionString("LoggerConnection");
contextConfigure.UseSqlServer(connectionString);
});
var app = builder.Build();
/* ... Configuring pipeline ... */
app.Run();
}
}
Configure logging
Logging configuration is set in code or via external sources, such as config files and environment variables. Using external configuration is beneficial when possible because it can be changed without rebuilding the application. However, some tasks, such as setting logging providers, can only be configured from code.
For apps that use a host, logging configuration is commonly provided by the "Logging" section of appsettings.{Environment}.json files. For apps that don't use a host, external configuration sources are set up explicitly or configured in code instead.
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
},
"SanlogLoggerProvider": {
"AppId": "e6bcc7df-e201-4d0b-02a3-08dbd09ffc89", // [Required] Here need to insert your specific application identifier
"IncludeScopes": true,
"LogLevel": { // [Optional] Override default log level configuration
"Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware": "Information"
}
}
}
}
Attention!
ODP.NETdoes supportGuids.Guids can be inserted into aRAW(16)column which is big enough to hold anyGuidvalue. But caution needs to be taken in order to handleGuids appropriately. This is due to the fact that as the .NETGuidstructure flips the byte values in reverse order for the integer-based parts of theGuidvalues whenGuid(byte[ ])constructor is used and when theToByteArray()method on theGuidstruct is invoked. More information: https://docs.oracle.com/en/database/oracle/oracle-database/23/odpnt/featGUID.html.- If using
EFCore.NamingConventionsyou must configureDbContextOptionsBuilderusing invokeUse*CaseNamingConventionin both places with the same method. It is the design time service that implementsIDesignTimeDbContextFactory<SanlogDbContext>and the second place is while configuring the Sanlog logger.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. 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. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- Leviasan.Sanlog.Abstractions (>= 1.1.3)
- Microsoft.EntityFrameworkCore (>= 8.0.6)
- Microsoft.Extensions.Hosting.Abstractions (>= 8.0.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 |
|---|