A Secure System Includes _____ That Can Log Every Instance of Data Entry and Changes.
Logging in Entity Framework Cadre
We often need to log the SQL and change tracking data for debugging purposes in EF Core.
EF Core logging automatically integrates with the logging mechanisms of .NET Core. So, learn well-nigh fundamentals of logging in .NET Core before implimenting logging in EF Core.
Entity Framework Core integrates with the .Net Cadre logging to log SQL and modify tracking information to the various output targets. First, install the Nuget package for logging provider of your choice and and so tie up the DbContext
to ILoggerFactory
.
Let'due south install the logging provider's NuGet package. Hither, we will brandish the logs on the console, so install the Microsoft.Extensions.Logging.Panel NuGet parcel from the NuGet Package Manager or execute the following command in the Package Managing director Console:
PM> Install-Packet Microsoft.Extensions.Logging.Console
The following figure illustrates how the DbContext
works with the logging API and panel logging provider.
After installing the console logger provider, yous need to create a static/singleton example of the LoggerFactory
and so tie it with a DbContext
, as shown below.
public form SchoolContext : DbContext { //static LoggerFactory object public static readonly ILoggerFactory loggerFactory = new LoggerFactory(new[] { new ConsoleLoggerProvider((_, __) => truthful, true) }); //or // public static readonly ILoggerFactory loggerFactory = new LoggerFactory().AddConsole((_,___) => truthful); public SchoolContext():base of operations() { } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseLoggerFactory(loggerFactory) //tie-up DbContext with LoggerFactory object .EnableSensitiveDataLogging() .UseSqlServer(@"Server=.\SQLEXPRESS;Database=SchoolDB;Trusted_Connection=True;"); } public DbSet<Student> Students { get; set; } }
In the in a higher place example, we have created an object of the LoggerFactory
form and assigned it to the ILoggerFactory
blazon static variable. And then, we passed this object in the optionsBuilder.UseLoggerFactory()
method in the OnConfiguring()
method. This volition enable the DbContext
to share the information with the loggerFactory
object, which in turn will display all the logging information on the console.
By default, EF Cadre volition not log sensitive data, such equally filter parameter values. So, call the EnableSensitiveDataLogging()
to log sensitive data.
The EF team recommends using the same logger factory object with all the instances of the DbContext
class during the application lifetime. Otherwise, it may upshot in a retention leak and poor performance. Y'all can also create a split factory class that provides y'all the singleton object of the LoggerFactory
class to use with the DbContext
.
Let's empathize the in a higher place example in detail.
First, we created an object of the LoggerFactory
form and assigned it to ILoggerFactory
type static variable, as shown below.
public static readonly ILoggerFactory loggerFactory = new LoggerFactory( new[] { new ConsoleLoggerProvider ((_, __) => true, true) } );
The LoggerFactory
tin can incorporate one or more logging providers which can be used to log to multiple mediums concurrently. The constructor of the LoggerFactory
have an array of different logger provider objects every bit new[] { }
. We want to display logs on the console, and then create an object of the panel logger provider ConsoleLoggerProvider
.
There are 4 constructors of the ConsoleLoggerProvider
. Use the one that allows lambda expression (Func<>) for log filtration and includeScope Boolean, as shown below.
new ConsoleLoggerProvider((_, __) => true, truthful)
Hither, nosotros don't desire to filter whatever information and so the lambda expression would always render truthful (_, __) => true
.
After creating an object of ILoggerFactory
, tied-upwards DbContext
with the ILoggerFactory
in the OnConfiguring()
method using the DbContextOptionsBuilder
.
optionsBuilder.UseLoggerFactory(loggerFactory)
Thus, we tied-up the DbContext
with the LoggerFactory
which includes the console logger provider. Now, we can encounter all the logs on the console whenever an instance of the DbContext
executes any action.
Consider the following example.
using (var context = new SchoolContext()) { var std = new Pupil(){ StudentName = "Steve" }; context.Add(std); context.SaveChanges(); Panel.ReadLine(); }
The above example will display the following logs on the console:
dbug: Microsoft.EntityFrameworkCore.Infrastructure[100401] dbug: Microsoft.EntityFrameworkCore.Database.Connection[200001] dbug: Microsoft.EntityFrameworkCore.Database.Connectedness[200003]
An 'IServiceProvider' was created for internal employ by Entity Framework.
info: Microsoft.EntityFrameworkCore.Infrastructure[100403]
Entity Framework Core 2.0.0-rtm-26452 initialized 'SchoolContext' using pr
ovider 'Microsoft.EntityFrameworkCore.SqlServer' with options: SensitiveDataLoggingEnabled
dbug: Microsoft.EntityFrameworkCore.Database.Connection[200000]
Opening connectedness to database 'SchoolDB' on server '.\SQLEXPRESS'.
Opened connection to database 'SchoolDB' on server '.\SQLEXPRESS'.
dbug: Microsoft.EntityFrameworkCore.Database.Transaction[200200]
Beginning transaction with isolation level 'ReadCommitted'.
warn: Microsoft.EntityFrameworkCore.Database.Command[100400]
Sensitive data logging is enabled. Log entries and exception messages may
include sensitive application data, this mode should merely be enabled during development.
dbug: Microsoft.EntityFrameworkCore.Database.Command[200100]
Executing DbCommand [Parameters=[@p0='' (DbType = DateTime2), @p1='' (DbTy
pe = Int32), @p2='0', @p3='' (Size = 8000) (DbType = Binary), @p4='Steve' (Size = 4000), @p5='0'], CommandType='Text', CommandTimeout='30']
Set NOCOUNT ON;
INSERT INTO [Students] ([DateOfBirth], [GradeId], [Height], [Photo], [Stud
entName], [Weight])
VALUES (@p0, @p1, @p2, @p3, @p4, @p5);
SELECT [StudentID]
FROM [Students]
WHERE @@ROWCOUNT = ane AND [StudentID] = scope_identity();
info: Microsoft.EntityFrameworkCore.Database.Control[200101]
Executed DbCommand (68ms) [Parameters=[@p0='' (DbType = DateTime2), @p1=''
(DbType = Int32), @p2='0', @p3='' (Size = 8000) (DbType = Binary), @p4='Steve'
(Size = 4000), @p5='0'], CommandType='Text', CommandTimeout='thirty']
Gear up NOCOUNT ON;
INSERT INTO [Students] ([DateOfBirth], [GradeId], [Height], [Photo], [Stud
entName], [Weight])
VALUES (@p0, @p1, @p2, @p3, @p4, @p5);
SELECT [StudentID]
FROM [Students]
WHERE @@ROWCOUNT = 1 AND [StudentID] = scope_identity();
dbug: Microsoft.EntityFrameworkCore.Database.Command[200300]
A information reader was disposed.
dbug: Microsoft.EntityFrameworkCore.Database.Transaction[200202]
Committing transaction.
dbug: Microsoft.EntityFrameworkCore.Database.Connection[200002]
Endmost connexion to database 'SchoolDB' on server '.\SQLEXPRESS'.
Closed connection to database 'SchoolDB' on server '.\SQLEXPRESS'.
dbug: Microsoft.EntityFrameworkCore.Database.Transaction[200204]
Disposing transaction.
As you can see, it logs all the information.
Filter Logs
In the above example, the DbContext
logged all the information while saving an entity. Erstwhile you don't want to log all the data and filter some unwanted logs. In EF Core, you can filter logs by specifying the logger category and log level.
Logger Categories
EF Core two.10 includes the DbLoggerCategory
class to get an Entity Framework Cadre logger categories using its Name belongings. The post-obit table lists different logger categories.
Logger Category Class | Description |
---|---|
Database.Command | Logger category for command execution, including SQL sent to database. |
Database.Connectedness | Logger category for db connection operations. |
Database.Transaction | Logger category for db transactions. |
Infrastructure | Logger category for miscellaneous messages for the EF infrastructure. |
Migration | Logger category for migrations. |
Model | Logger category for model edifice and metadata. |
Query | Logger category for queries (excluding generated SQL). |
Scaffolding | Logger category for scaffolding and reverse engineering. |
Update | Logger category for DbContext.SaveChanges() letters. |
Log SQL Queries
To log only SQL queries, specify the DbLoggerCategory.Database.Command
category and LogLevel.Information
in the lambda expression in the constructor of the ConsoleLoggerProvider
, every bit shown below.
public static readonly ILoggerFactory consoleLoggerFactory = new LoggerFactory(new[] { new ConsoleLoggerProvider((category, level) => category == DbLoggerCategory.Database.Command.Proper noun && level == LogLevel.Information, true) });
Or, merely telephone call the AddConsole()
method on LoggerFactory to log SQL queries, by default.
public static readonly ILoggerFactory consoleLoggerFactory = new LoggerFactory().AddConsole();
Now, this will log the post-obit query information which saving an entity using the DbContext
.
info: Microsoft.EntityFrameworkCore.Database.Command[200101]
Executed DbCommand (73ms) [Parameters=[@p0='' (DbType = DateTime2), @p1=''
(DbType = Int32), @p2='0', @p3='' (Size = 8000) (DbType = Binary), @p4='Steve'
(Size = 4000), @p5='0'], CommandType='Text', CommandTimeout='30']
Fix NOCOUNT ON;
INSERT INTO [Students] ([DateOfBirth], [GradeId], [Top], [Photograph], [Stud
entName], [Weight])
VALUES (@p0, @p1, @p2, @p3, @p4, @p5);
SELECT [StudentID]
FROM [Students]
WHERE @@ROWCOUNT = i AND [StudentID] = scope_identity();
Source: https://www.entityframeworktutorial.net/efcore/logging-in-entityframework-core.aspx
Post a Comment for "A Secure System Includes _____ That Can Log Every Instance of Data Entry and Changes."