|
1 | 1 | # Logging |
2 | 2 |
|
3 | | -Npgsql uses Microsoft.Extensions.Logging to emit log events that can be routed to your logging library of choice - see [their docs](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging) for more information. Note that Microsoft.Extensions.Logging support replaced Npgsql's own custom logging wrapper in 3.2. |
| 3 | +*Note:* Npgsql 3.2.0 and 3.2.1 siginifiantly changed logging to use Microsoft.Extensions.Logging. After several complaints and issues (see [#1504](https://github.com/npgsql/npgsql/issues/1504)), this feature was rolled back. Starting with Npgsql 3.2.2, logging support is identical to Npgsql 3.1. |
4 | 4 |
|
5 | | -Since Npgsql is an ADO.NET provider and does not support dependency injection, you must manually inject your ILoggingFactory by including the following code *before* starting to use any of Npgsql's other APIs. For example, to log to the console, install `Microsoft.Extensions.Logging.Console` and add the following code: |
| 5 | +Npgsql includes a built-in feature for outputting logging events which can help debug issues. |
| 6 | + |
| 7 | +Npgsql logging is disabled by default and must be turned on. Logging can be turned on by setting `NpgsqlLogManager.Provider` to a class implementing the `INpgsqlLoggingProvider` interface. Npgsql comes with a console implementation which can be set up as follows: |
| 8 | + |
| 9 | +```c# |
| 10 | +NpgsqlLogManager.Provider = new ??? |
| 11 | +``` |
| 12 | + |
| 13 | +*Note: you must set the logging provider before invoking any other Npgsql method, at the very start of your program.* |
| 14 | + |
| 15 | +It's trivial to create a logging provider that passes log messages to whatever logging framework you use. You can find such an adaptor for NLog [here](http://ni). |
| 16 | + |
| 17 | +*Note:* the logging API is a first implementation and will probably improve/change - don't treat it as a stable part of the Npgsql API. Let us know if you think there are any missing messages or features! |
| 18 | + |
| 19 | +## ConsoleLoggingProvider |
| 20 | + |
| 21 | +Npgsql comes with one built-in logging provider: ConsoleLoggingProvider. It will simply dump all log messages with a given level or above to stdanrd output. |
| 22 | +You can set it up by including the following line at the beginning of your application: |
6 | 23 |
|
7 | 24 | ```c# |
8 | | -NpgsqlLogManager.LoggerFactory = new LoggerFactory() |
9 | | - .AddConsole((text, logLevel) => logLevel >= LogLevel.Debug); |
| 25 | +NpgsqlLogManager.Provider = new ConsoleLoggingProvider(<min level>, <print level?>, <print connector id?>); |
10 | 26 | ``` |
11 | 27 |
|
12 | | -This will make Npgsql log to the console, for messages of at least Debug level. Other providers exist for NLog and other logging packages and services. |
| 28 | +Level defaults to `NpgsqlLogLevel.Info` (which will only print warnings and errors). |
| 29 | +You can also have log levels and connector IDs logged. |
13 | 30 |
|
14 | 31 | ## Statement and Parameter Logging |
15 | 32 |
|
16 | 33 | Npgsql will log all SQL statements at level Debug, this can help you debug exactly what's being sent to PostgreSQL. |
17 | 34 |
|
18 | 35 | By default, Npgsql will not log parameter values as these may contain sensitive information. You can turn on |
19 | 36 | parameter logging by setting `NpgsqlLogManager.IsParameterLoggingEnabled` to true. |
| 37 | + |
| 38 | +## NLogLoggingProvider (or implementing your own) |
| 39 | + |
| 40 | +The following provider is used in the Npgsql unit tests to pass log messages to [NLog](http://nlog-project.org/). |
| 41 | +You're welcome to copy-paste it into your project, or to use it as a starting point for implementing your own custom provider. |
| 42 | + |
| 43 | +```c# |
| 44 | +class NLogLoggingProvider : INpgsqlLoggingProvider |
| 45 | +{ |
| 46 | + public NpgsqlLogger CreateLogger(string name) |
| 47 | + { |
| 48 | + return new NLogLogger(name); |
| 49 | + } |
| 50 | +} |
| 51 | + |
| 52 | +class NLogLogger : NpgsqlLogger |
| 53 | +{ |
| 54 | + readonly Logger _log; |
| 55 | + |
| 56 | + internal NLogLogger(string name) |
| 57 | + { |
| 58 | + _log = LogManager.GetLogger(name); |
| 59 | + } |
| 60 | + |
| 61 | + public override bool IsEnabled(NpgsqlLogLevel level) |
| 62 | + { |
| 63 | + return _log.IsEnabled(ToNLogLogLevel(level)); |
| 64 | + } |
| 65 | + |
| 66 | + public override void Log(NpgsqlLogLevel level, int connectorId, string msg, Exception exception = null) |
| 67 | + { |
| 68 | + var ev = new LogEventInfo(ToNLogLogLevel(level), "", msg); |
| 69 | + if (exception != null) |
| 70 | + ev.Exception = exception; |
| 71 | + if (connectorId != 0) |
| 72 | + ev.Properties["ConnectorId"] = connectorId; |
| 73 | + _log.Log(ev); |
| 74 | + } |
| 75 | + |
| 76 | + static LogLevel ToNLogLogLevel(NpgsqlLogLevel level) |
| 77 | + { |
| 78 | + switch (level) |
| 79 | + { |
| 80 | + case NpgsqlLogLevel.Trace: |
| 81 | + return LogLevel.Trace; |
| 82 | + case NpgsqlLogLevel.Debug: |
| 83 | + return LogLevel.Debug; |
| 84 | + case NpgsqlLogLevel.Info: |
| 85 | + return LogLevel.Info; |
| 86 | + case NpgsqlLogLevel.Warn: |
| 87 | + return LogLevel.Warn; |
| 88 | + case NpgsqlLogLevel.Error: |
| 89 | + return LogLevel.Error; |
| 90 | + case NpgsqlLogLevel.Fatal: |
| 91 | + return LogLevel.Fatal; |
| 92 | + default: |
| 93 | + throw new ArgumentOutOfRangeException("level"); |
| 94 | + } |
| 95 | + } |
| 96 | +} |
| 97 | +``` |
0 commit comments