シンプルなログSimple Logging

注意

この機能は EF Core 5.0 で導入されました。This feature was introduced in EF Core 5.0.

ヒント

この記事のサンプルは GitHub からダウンロードできます。You can download this article's sample from GitHub.

Entity Framework Core (EF Core) 単純なログを使用して、アプリケーションの開発とデバッグを行うときに簡単にログを取得できます。Entity Framework Core (EF Core) simple logging can be used to easily obtain logs while developing and debugging applications. この形式のログ記録では、最小限の構成と追加の NuGet パッケージは必要ありません。This form of logging requires minimal configuration and no additional NuGet packages.

ヒント

また EF Core は、さらに多くの構成を必要とする が、多くの場合、実稼働アプリケーションでのログ記録に適しています。EF Core also integrates with Microsoft.Extensions.Logging, which requires more configuration, but is often more suitable for logging in production applications.

構成Configuration

DbContext インスタンスの構成時に LogTo を使用すると、任意の種類のアプリケーションから EF Core ログにアクセスできます。EF Core logs can be accessed from any type of application through the use of LogTo when configuring a DbContext instance. この構成は、通常、DbContext.OnConfiguring のオーバーライドで行われます。This configuration is commonly done in an override of DbContext.OnConfiguring. 次に例を示します。For example:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder.LogTo(Console.WriteLine);

LogToまたは、の一部として、 AddDbContext または DbContextOptions コンストラクターに渡すインスタンスを作成するときに、を呼び出すことができ DbContext ます。Alternately, LogTo can be called as part of AddDbContext or when creating a DbContextOptions instance to pass to the DbContext constructor.

ヒント

AddDbContext が使用されている場合、または DbContext コンストラクターに DbContextOptions インスタンスが渡された場合、OnConfiguring は引き続き呼び出されます。OnConfiguring is still called when AddDbContext is used or a DbContextOptions instance is passed to the DbContext constructor. これにより、DbContext の構築方法に関係なく、コンテキスト構成を適用するための理想的な場所となります。This makes it the ideal place to apply context configuration regardless of how the DbContext is constructed.

ログの指示Directing the logs

コンソールへのログ記録Logging to the console

LogToAction<T>文字列を受け入れるデリゲートが必要です。LogTo requires an Action<T> delegate that accepts a string. EF Core は、生成されたログメッセージごとに文字列を使用して、このデリゲートを呼び出します。EF Core will call this delegate with a string for each log message generated. 次に、指定されたメッセージで何かを実行するデリゲートが作成されます。It is then up to the delegate to do something with the given message.

Console.WriteLineこのデリゲートには、前述のようにメソッドがよく使用されます。The Console.WriteLine method is often used for this delegate, as shown above. この結果、各ログメッセージがコンソールに書き込まれます。This results in each log message being written to the console.

[デバッグ] ウィンドウへのログ記録Logging to the debug window

Debug.WriteLine は、Visual Studio または他の Ide のデバッグウィンドウに出力を送信するために使用できます。Debug.WriteLine can be used to send output to the Debug window in Visual Studio or other IDEs. この場合、クラスはリリースビルドからコンパイルされるため、ラムダ構文を使用する必要があり Debug ます。Lambda syntax must be used in this case because the Debug class is compiled out of release builds. 例:For example:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder.LogTo(message => Debug.WriteLine(message));

ファイルへのログ記録Logging to a file

ファイルに書き込むに StreamWriter は、ファイルのまたは同様のを作成する必要があります。Writing to a file requires creating a StreamWriter or similar for the file. この WriteLine メソッドは、上記の他の例のように使用できます。The WriteLine method can then be used as in the other examples above. コンテキストが破棄されたときにライターを破棄することによって、ファイルが正常に閉じられていることを確認してください。Remember to ensure the file is closed cleanly by disposing the writer when the context is disposed. 例:For example:

private readonly StreamWriter _logStream = new StreamWriter("mylog.txt", append: true);

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder.LogTo(_logStream.WriteLine);

public override void Dispose()
{
    base.Dispose();
    _logStream.Dispose();
}

public override async ValueTask DisposeAsync()
{
    await base.DisposeAsync();
    await _logStream.DisposeAsync();
}

ヒント

実稼働アプリケーションのファイルへのログ記録には、 Microsoft の拡張子 を使用することを検討してください。Consider using Microsoft.Extensions.Logging for logging to files in production applications.

詳細なメッセージを取得するGetting detailed messages

機微なデータSensitive data

既定では、EF Core には、例外メッセージ内のデータの値は含まれません。By default, EF Core will not include the values of any data in exception messages. これは、このようなデータは機密情報である可能性があるため、例外が処理されない場合に実稼働環境でも明らかになる可能性があるためです。This is because such data may be confidential, and could be revealed in production use if an exception is not handled.

ただし、特にキーのデータ値を把握することは、デバッグ時に非常に役立ちます。However, knowing data values, especially for keys, can be very helpful when debugging. これは、を呼び出すことによって EF Core で有効にすることができ EnableSensitiveDataLogging() ます。This can be enabled in EF Core by calling EnableSensitiveDataLogging(). 例:For example:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder
        .LogTo(Console.WriteLine)
        .EnableSensitiveDataLogging();

詳細なクエリの例外Detailed query exceptions

パフォーマンス上の理由により、EF Core は、try-catch ブロック内のデータベースプロバイダーから値を読み取る各呼び出しをラップしません。For performance reasons, EF Core does not wrap each call to read a value from the database provider in a try-catch block. ただし、これにより、特に、モデルで許可されていない場合にデータベースが NULL を返す場合に、診断が困難な例外が発生することがあります。However, this sometimes results in exceptions that are hard to diagnose, especially when the database returns a NULL when not allowed by the model.

オンに EnableDetailedErrors すると、EF によってこれらの try-catch ブロックが導入されるため、より詳細なエラーが発生します。Turning on EnableDetailedErrors will cause EF to introduce these try-catch blocks and thereby provide more detailed errors. 例:For example:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder
        .LogTo(Console.WriteLine)
        .EnableDetailedErrors();

フィルター処理Filtering

ログ レベルLog levels

すべての EF Core ログメッセージは、列挙型によって定義されたレベルに割り当てられ LogLevel ます。Every EF Core log message is assigned to a level defined by the LogLevel enum. 既定では EF Core 簡易ログ記録には、レベル以上のすべてのメッセージが含まれ Debug ます。By default, EF Core simple logging includes every message at Debug level or above. LogTo は、一部のメッセージをフィルターで除外するために、より高いレベルを渡すことができます。LogTo can be passed a higher minimum level to filter out some messages. たとえば、を渡す Information と、データベースアクセスと一部のハウスキーピングメッセージに限定されたログの最小セットが得られます。For example, passing Information results in a minimal set of logs limited to database access and some housekeeping messages.

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder.LogTo(Console.WriteLine, LogLevel.Information);

特定のメッセージSpecific messages

すべてのログメッセージにはが割り当てられ EventId ます。Every log message is assigned an EventId. これらの Id CoreEventId には、クラスから、または RelationalEventId リレーショナル固有のメッセージのクラスからアクセスできます。These IDs can be accessed from the CoreEventId class or the RelationalEventId class for relational-specific messages. データベースプロバイダーには、同様のクラスのプロバイダー固有の Id が含まれる場合もあります。A database provider may also have provider-specific IDs in a similar class. たとえば、 SqlServerEventId SQL Server プロバイダーの場合はです。For example, SqlServerEventId for the SQL Server provider.

LogTo は、1つまたは複数のイベント Id に関連付けられたメッセージのみをログに記録するように構成できます。LogTo can be configured to only log the messages associated with one or more event IDs. たとえば、初期化または破棄されたコンテキストのメッセージのみをログに記録するには、次のようにします。For example, to log only messages for the context being initialized or disposed:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder
        .LogTo(Console.WriteLine, new[] { CoreEventId.ContextDisposed, CoreEventId.ContextInitialized });

メッセージの種類Message categories

すべてのログメッセージは、名前付きの階層 logger カテゴリに割り当てられます。Every log message is assigned to a named hierarchical logger category. カテゴリは次のとおりです。The categories are:

カテゴリCategory メッセージMessages
Microsoft.EntityFrameworkCoreMicrosoft.EntityFrameworkCore すべての EF Core メッセージAll EF Core messages
Microsoft EntityFrameworkCore. データベースMicrosoft.EntityFrameworkCore.Database すべてのデータベースの相互作用All database interactions
Microsoft EntityFrameworkCore. Database. ConnectionMicrosoft.EntityFrameworkCore.Database.Connection データベース接続の使用Uses of a database connection
Microsoft EntityFrameworkCore. Database. CommandMicrosoft.EntityFrameworkCore.Database.Command データベースコマンドの使用Uses of a database command
Microsoft EntityFrameworkCore. Database. TransactionMicrosoft.EntityFrameworkCore.Database.Transaction データベーストランザクションの使用Uses of a database transaction
Microsoft EntityFrameworkCore. 更新プログラムMicrosoft.EntityFrameworkCore.Update エンティティの保存、データベースとのやり取りの除外Saving entities, excluding database interactions
Microsoft EntityFrameworkCore. ModelMicrosoft.EntityFrameworkCore.Model すべてのモデルとメタデータの相互作用All model and metadata interactions
Microsoft EntityFrameworkCore。検証Microsoft.EntityFrameworkCore.Model.Validation モデルの検証Model validation
Microsoft EntityFrameworkCore. QueryMicrosoft.EntityFrameworkCore.Query クエリ、データベースとのやり取りの除外Queries, excluding database interactions
Microsoft EntityFrameworkCore インフラストラクチャMicrosoft.EntityFrameworkCore.Infrastructure 一般的なイベント (コンテキストの作成など)General events, such as context creation
Microsoft EntityFrameworkCore. スキャフォールディングMicrosoft.EntityFrameworkCore.Scaffolding データベースのリバースエンジニアリングDatabase reverse engineering
Microsoft EntityFrameworkCore. 移行Microsoft.EntityFrameworkCore.Migrations 移行Migrations
Microsoft EntityFrameworkCore. ChangeTrackingMicrosoft.EntityFrameworkCore.ChangeTracking 変更の追跡の相互作用Change tracking interactions

LogTo は、1つまたは複数のカテゴリからのメッセージのみをログに記録するように構成できます。LogTo can be configured to only log the messages from one or more categories. たとえば、データベースの相互作用のみをログに記録するには、次のようにします。For example, to log only database interactions:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder
        .LogTo(Console.WriteLine, new[] { DbLoggerCategory.Database.Name });

クラスは、 DbLoggerCategory カテゴリを検索するための階層的な API を提供し、文字列をハードコーディングする必要がないことに注意してください。Notice that the DbLoggerCategory class provides a hierarchical API for finding a category and avoids the need to hard-code strings.

カテゴリは階層構造であるため、カテゴリを使用するこの例に Database は、サブカテゴリのすべてのメッセージ (、、および) が含まれ Database.Connection Database.Command Database.Transaction ます。Since categories are hierarchical, this example using the Database category will include all messages for the subcategories Database.Connection, Database.Command, and Database.Transaction.

カスタム フィルターCustom filters

LogTo 上のフィルターオプションが十分でない場合に、カスタムフィルターを使用できるようにします。LogTo allows a custom filter to be used for cases where none of the filtering options above are sufficient. たとえば、レベル以上のメッセージ、 Information および接続を開いたり閉じたりするためのメッセージをログに記録する場合は、次のようになります。For example, to log any message at level Information or above, as well as messages for opening and closing a connection:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder
        .LogTo(
            Console.WriteLine,
            (eventId, logLevel) => logLevel >= LogLevel.Information
                                   || eventId == RelationalEventId.ConnectionOpened
                                   || eventId == RelationalEventId.ConnectionClosed);

ヒント

カスタムフィルターを使用したフィルター処理、またはここに示されている他のオプションの使用は、デリゲートでのフィルター処理よりも効率的です LogToFiltering using custom filters or using any of the other options shown here is more efficient than filtering in the LogTo delegate. これは、フィルターによってメッセージがログに記録されないと判断された場合、ログメッセージは作成されません。This is because if the filter determines the message should not be logged, then the log message is not even created.

特定のメッセージの構成Configuration for specific messages

EF Core ConfigureWarnings API を使用すると、特定のイベントが発生したときの動作をアプリケーションで変更できます。The EF Core ConfigureWarnings API allows applications to change what happens when a specific event is encountered. これは次の場合に使用できます。This can be used to:

  • イベントがログに記録されるログレベルを変更するChange the log level at which the event is logged
  • イベントのログ記録をスキップするSkip logging the event altogether
  • イベントが発生したときに例外をスローするThrow an exception when the event occurs

イベントのログレベルの変更Changing the log level for an event

前の例では、カスタムフィルターを使用して、 LogLevel.Information のすべてのメッセージと、に対して定義されている2つのイベントをログに記録して LogLevel.Debug います。The previous example used a custom filter to log every message at LogLevel.Information as well as two events defined for LogLevel.Debug. 次の2つのイベントのログレベルをに変更することで、同じことを実現でき Debug Information ます。The same can be achieved by changing the log level of the two Debug events to Information:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder
        .ConfigureWarnings(
            b => b.Log(
                (RelationalEventId.ConnectionOpened, LogLevel.Information),
                (RelationalEventId.ConnectionClosed, LogLevel.Information)))
        .LogTo(Console.WriteLine, LogLevel.Information);

イベントのログ記録を抑制するSuppress logging an event

同様に、個々のイベントをログに記録しないようにすることもできます。In a similar way, an individual event can be suppressed from logging. これは、確認して理解した警告を無視する場合に特に便利です。This is particularly useful for ignoring a warning that has been reviewed and understood. 例:For example:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder
        .ConfigureWarnings(b => b.Ignore(CoreEventId.DetachedLazyLoadingWarning))
        .LogTo(Console.WriteLine);

イベントに対してスローするThrow for an event

最後に、特定のイベントに対してをスローするように EF Core を構成できます。Finally, EF Core can be configured to throw for a given event. これは、警告をエラーに変更する場合に特に便利です。This is particularly useful for changing a warning into an error. (実際には、これはメソッドの本来の目的であるため、という ConfigureWarnings 名前です)。例えば:(Indeed, this was the original purpose of ConfigureWarnings method, hence the name.) For example:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder
        .ConfigureWarnings(b => b.Throw(RelationalEventId.MultipleCollectionIncludeWarning))
        .LogTo(Console.WriteLine);

メッセージの内容と書式設定Message contents and formatting

の既定の内容 LogTo は、複数の行にわたって書式設定されます。The default content from LogTo is formatted across multiple lines. 最初の行には、メッセージのメタデータが含まれています。The first line contains message metadata:

  • LogLevel4 文字のプレフィックスとしてのThe LogLevel as a four-character prefix
  • 現在のカルチャに対して書式設定されたローカルタイムスタンプA local timestamp, formatted for the current culture
  • EventIdコピー/貼り付けを使用して、 CoreEventId または他のいずれかのクラスからのメンバーを取得し、 EventId 生の ID 値を含む、フォーム内の。The EventId in the form that can be copy/pasted to get the member from CoreEventId or one of the other EventId classes, plus the raw ID value
  • 前に説明したように、イベントカテゴリ。The event category, as described above.

例:For example:

info: 10/6/2020 10:52:45.581 RelationalEventId.CommandExecuted[20101] (Microsoft.EntityFrameworkCore.Database.Command)
      Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      CREATE TABLE "Blogs" (
          "Id" INTEGER NOT NULL CONSTRAINT "PK_Blogs" PRIMARY KEY AUTOINCREMENT,
          "Name" INTEGER NOT NULL
      );
dbug: 10/6/2020 10:52:45.582 RelationalEventId.TransactionCommitting[20210] (Microsoft.EntityFrameworkCore.Database.Transaction)
      Committing transaction.
dbug: 10/6/2020 10:52:45.585 RelationalEventId.TransactionCommitted[20202] (Microsoft.EntityFrameworkCore.Database.Transaction)
      Committed transaction.

このコンテンツは DbContextLoggerOptions 、次のセクションに示すように、から値を渡すことによってカスタマイズできます。This content can be customized by passing values from DbContextLoggerOptions, as shown in the following sections.

ヒント

ログの書式設定をより詳細に制御するには、 Microsoft の拡張子 を使用することを検討してください。Consider using Microsoft.Extensions.Logging for more control over log formatting.

UTC 時刻の使用Using UTC time

既定では、タイムスタンプはデバッグ中にローカルで使用するように設計されています。By default, timestamps are designed for local consumption while debugging. DbContextLoggerOptions.DefaultWithUtcTime代わりに、カルチャに依存しない UTC タイムスタンプを使用するためにを使用します。ただし、その他はすべて同じままにしておきます。Use DbContextLoggerOptions.DefaultWithUtcTime to use culture-agnostic UTC timestamps instead, but keep everything else the same. 例:For example:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder.LogTo(
        Console.WriteLine,
        LogLevel.Debug,
        DbContextLoggerOptions.DefaultWithUtcTime);

この例では、次のようにログの書式が設定されます。This example results in the following log formatting:

info: 2020-10-06T17:55:39.0333701Z RelationalEventId.CommandExecuted[20101] (Microsoft.EntityFrameworkCore.Database.Command)
      Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      CREATE TABLE "Blogs" (
          "Id" INTEGER NOT NULL CONSTRAINT "PK_Blogs" PRIMARY KEY AUTOINCREMENT,
          "Name" INTEGER NOT NULL
      );
dbug: 2020-10-06T17:55:39.0333892Z RelationalEventId.TransactionCommitting[20210] (Microsoft.EntityFrameworkCore.Database.Transaction)
      Committing transaction.
dbug: 2020-10-06T17:55:39.0351684Z RelationalEventId.TransactionCommitted[20202] (Microsoft.EntityFrameworkCore.Database.Transaction)
      Committed transaction.

単一行のログ記録Single line logging

ログメッセージごとに1行だけを取得すると便利な場合があります。Sometimes it is useful to get exactly one line per log message. これは、で有効にすることができ DbContextLoggerOptions.SingleLine ます。This can be enabled by DbContextLoggerOptions.SingleLine. 例:For example:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder.LogTo(
        Console.WriteLine,
        LogLevel.Debug,
        DbContextLoggerOptions.DefaultWithLocalTime | DbContextLoggerOptions.SingleLine);

この例では、次のようにログの書式が設定されます。This example results in the following log formatting:

info: 10/6/2020 10:52:45.723 RelationalEventId.CommandExecuted[20101] (Microsoft.EntityFrameworkCore.Database.Command) -> Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30']CREATE TABLE "Blogs" (    "Id" INTEGER NOT NULL CONSTRAINT "PK_Blogs" PRIMARY KEY AUTOINCREMENT,    "Name" INTEGER NOT NULL);
dbug: 10/6/2020 10:52:45.723 RelationalEventId.TransactionCommitting[20210] (Microsoft.EntityFrameworkCore.Database.Transaction) -> Committing transaction.
dbug: 10/6/2020 10:52:45.725 RelationalEventId.TransactionCommitted[20202] (Microsoft.EntityFrameworkCore.Database.Transaction) -> Committed transaction.

その他のコンテンツオプションOther content options

の他のフラグを DbContextLoggerOptions 使用して、ログに含まれるメタデータの量を減らすことができます。Other flags in DbContextLoggerOptions can be used to trim down the amount of metadata included in the log. これは、単一行ログと組み合わせて使用すると便利です。This is can be useful in conjunction with single-line logging. 例:For example:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder.LogTo(
        Console.WriteLine,
        LogLevel.Debug,
        DbContextLoggerOptions.UtcTime | DbContextLoggerOptions.SingleLine);

この例では、次のようにログの書式が設定されます。This example results in the following log formatting:

2020-10-06T17:52:45.7320362Z -> Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30']CREATE TABLE "Blogs" (    "Id" INTEGER NOT NULL CONSTRAINT "PK_Blogs" PRIMARY KEY AUTOINCREMENT,    "Name" INTEGER NOT NULL);
2020-10-06T17:52:45.7320531Z -> Committing transaction.
2020-10-06T17:52:45.7339441Z -> Committed transaction.

EF6 からの移動Moving from EF6

EF Core 単純なログ記録は、 Database.Log 次の2つの重要な点で EF6 で異なります。EF Core simple logging differs from Database.Log in EF6 in two important ways:

  • ログメッセージは、データベースとの対話のみに制限されません。Log messages are not limited to only database interactions
  • ログは、コンテキストの初期化時に構成する必要があります。The logging must be configured at context initialization time

最初の違いとして、上記のフィルター処理を使用して、ログに記録するメッセージを制限できます。For the first difference, the filtering described above can be used to limit which messages are logged.

2番目の違いは、不要になったログメッセージを生成しないことで、パフォーマンスを向上させるための意図的な変更です。The second difference is an intentional change to improve performance by not generating log messages when they are not needed. ただし、でプロパティを作成し、設定されている場合にのみ使用することで、EF6 と同様の動作を実現でき Log DbContext ます。However, it is still possible to get a similar behavior to EF6 by creating a Log property on your DbContext and then using it only when it has been set. 次に例を示します。For example:

public Action<string> Log { get; set; }

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder.LogTo(s => Log?.Invoke(s));