آموزشگاه برنامه نویسی تحلیل داده
آموزشگاه برنامه نویسی تحلیل داده

آموزش مکانیزم Logging در Entity Framework Core

دوره های مرتبط با این مقاله

آموزش مکانیزم Logging در Entity Framework Core

اغلب می خواهیم اطلاعات SQL و change tracking را برای debug کردن برنامه log کنیم.

مکانیزم log در EF Core به طور خودکار با مکانیزم های Logging در .NET Core ترکیب می شود. پیش از پیاده سازی logging در EF Core، درمورد مفاهیم پایه ی logging در .Net Core مطالعه کنید.

ابتدا Nuget package لازم برای logging providerمورد نظرتان را نصب کنید و DbContext را به ILoggerFactory مرتبط کنید. در اینجا می خواهیم log ها را در کنسول نمایش دهیم. برای نصب Nuget Package لازم، دستور زیر را در PMC اجرا کنید:


PM> Install-Package Microsoft.Extensions.Logging.Console

تصویر زیر نشان می دهد DbContext چگونه با logging API و console logging provider کار می کند:


پس از نصب console logger provider باید یک instance به صورت static/singleton از LoggerFactory بسازید و آن را به DbContext وصل کنید.


public class SchoolContext : DbContext
{
    //static LoggerFactory object
    public static readonly ILoggerFactory loggerFactory = new LoggerFactory(new[] {
              new ConsoleLoggerProvider((_, __) => true, true)
        });
    //or
    // public static readonly ILoggerFactory loggerFactory  = new LoggerFactory().AddConsole((_,___) => true);
    
    public SchoolContext():base()
    {
    }
    
    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; }
}

در مثال بالا یک object از کلاس LoggerFactory ساختیم و آن را به متغیر استاتیک از نوع ILoggerFactory نسبت دادیم. سپس در متد OnConfiguring() این object را به متد optionsBuilder.UseLoggerFactory() پاس دادیم. این کار باعث می شود DbContext بتواند اطلاعات را با loggerFactory به اشتراک بگذارد، و در نهایت این اطلاعات log شده در کنسول نمایش داده شود.

به طور پیش فرض EF Core اطلاعات حساس مثل مقادیر filter parameter را log نمی کند. متد EnableSensitiveDataLogging() را برای لاگ Dataی حساس فراخوانی کنید.

توجه: بهتر است از یک logger factory object برای همه ی instance های DbContext در طول چرخه حیات برنامه استفاده کنید. در غیر این صورت، مشکلات performance و memory leak بوجود می آید. می توانید از یک factory class جداگانه که LoggerFactory را بصورت singleton در اختیار می گذارد با DbContext استفاده کنید.

می خواهیم مثال بالا را با جزئیات بررسی کنیم.

ابتدا یک شی از کلاس LoggerFactory ساختیم و آن را به متغیر استاتیک از نوع ILoggerFactory نسبت دادیم:


public static readonly ILoggerFactory loggerFactory = new LoggerFactory(
    new[] { new ConsoleLoggerProvider ((_, __) => true, true) }
)

LoggerFactory می تواند حاوی یک یا چند logging provider باشد که برای لاگ چند محیط هم زمان بکار روند. سازنده ی LoggerFactory آرایه ای از logger provider object های مختلف می پذیرد. می خواهیم log ها را در کنسول نمایش دهیم، پس یک شی از ConsoleLoggerProvider می سازیم.

چهار سازنده برای ConsoleLoggerProvider وجود دارد. از سازنده ای که امکان استفاده از lambda expression (Func<>) می دهد برای log filtration و includeScope Boolean به صورت زیر استفاده کنید:


new ConsoleLoggerProvider((_, __) => true, true)

اینجا نمی خواهیم هیچ اطلاعاتی را فیلتر کنیم، پس lambda expression همواره true بر می گرداند: (_, __) => true پس از ساختن یک شی از ILoggerFactory، در متدOnConfiguring()شی DbContext را با استفاده از DbContextOptionsBuilder به ILoggerFactory مرتبط می کنیم.


optionsBuilder.UseLoggerFactory(loggerFactory)

حال می توانیم هرزمان که نمونه ای از DbContext کاری انجام می دهد، همه ی log ها را در console ببینیم. مثال زیر را در نظر بگیرید:


using (var context = new SchoolContext())
{
    var std = new Student(){ StudentName = "Steve" };
    context.Add(std);
                
    context.SaveChanges();
    Console.ReadLine();
}

مثال بالا log زیر را در کنسول نشان می دهد:


dbug: Microsoft.EntityFrameworkCore.Infrastructure[100401] 
An 'IServiceProvider' was created for internal use 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 connection to database 'SchoolDB' on server '.\SQLEXPRESS'. 
dbug: Microsoft.EntityFrameworkCore.Database.Connection[200001] 
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 only 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 = 1 AND [StudentID] = scope_identity(); 
info: Microsoft.EntityFrameworkCore.Database.Command[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='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 = 1 AND [StudentID] = scope_identity(); 
dbug: Microsoft.EntityFrameworkCore.Database.Command[200300] 
A data reader was disposed. 
dbug: Microsoft.EntityFrameworkCore.Database.Transaction[200202] 
Committing transaction. 
dbug: Microsoft.EntityFrameworkCore.Database.Connection[200002] 
Closing connection to database 'SchoolDB' on server '.\SQLEXPRESS'. 
dbug: Microsoft.EntityFrameworkCore.Database.Connection[200003] 
Closed connection to database 'SchoolDB' on server '.\SQLEXPRESS'. 
dbug: Microsoft.EntityFrameworkCore.Database.Transaction[200204] 
Disposing transaction

همانطور که می بینید همه ی اطلاعات را log کرده است.

فیلتر کردن log ها

در مثال بالا، DbContext تمام اطلاعات را حین ذخیره ی موجودیت log می کند. گاهی می خواهیم بخشی از log ها را فیلتر کنیم. در EF Core می توانید log ها را با مشخص کردن logger category و log level فیلتر کنید.

Logger Category

EF Core 2.x شامل کلاس DbLoggerCategory است که بوسیله آن می توان Logger Category ها را با استفاده از Name Property شان گرفت. جدول زیر Logger Category های مختلف را نشان می دهد:

Description
Logger Category Class
Logger category for command execution, including SQL sent to database.
Database.Command
Logger category for db connection operations.
Database.Connection
Logger category for db transactions.
Database.Transaction
Logger category for miscellaneous messages for the EF infrastructure.
Infrastructure
Logger category for migrations.
Migration
Logger category for model building and metadata.
Model
Logger category for queries (excluding generated SQL).
Query
Logger category for scaffolding and reverse engineering.
Scaffolding
Logger category for DbContext.SaveChanges() messages.
Update

Log کردن SQL Query

برای log کردن SQL Query ها، از DbLoggerCategory.Database.Command به عنوان category و LogLevel.Information در lambda expression درون سازنده ی ConsoleLoggerProvider استفاده کنید. در زیر نشان داده ایم:


public static readonly ILoggerFactory consoleLoggerFactory  
            = new LoggerFactory(new[] {
                  new ConsoleLoggerProvider((category, level) =>
                    category == DbLoggerCategory.Database.Command.Name &&
                    level == LogLevel.Information, true)
                });

یا فقط متد AddConsole() را روی LoggerFactory فراخوانی کنید


public static readonly ILoggerFactory consoleLoggerFactory
         = new LoggerFactory().AddConsole();

حال نتیجه log عملیات ذخیره موجودیت توسط 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'] 
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 = 1 AND [StudentID] = scope_identity();

  • 194
  •    0
  • تاریخ ارسال :   1398/06/28

دانشجویان گرامی اگر این مطلب برای شما مفید بود لطفا ما را در GooglePlus محبوب کنید
رمز عبور: tahlildadeh.com یا www.tahlildadeh.com
ارسال دیدگاه نظرات کاربران
شماره موبایل دیدگاه
عنوان پست الکترونیک

ارسال

آموزشگاه برنامه نویسی تحلیل داده
آموزشگاه برنامه نویسی تحلیل داده

تمامی حقوق این سایت متعلق به آموزشگاه تحلیل داده می باشد .