NLog со строкой соединения Entity Framework? - PullRequest
7 голосов
/ 04 февраля 2012

Я пытаюсь использовать 'Database' NLog target и хотел бы, чтобы NLog прочитал мою строку подключения, чтобы избежать необходимости устанавливать ее дважды в одном и том же файле конфигурации.Проблема в том, что у меня есть строка подключения в стиле Entity Framework , поэтому использование атрибута connectionStringName не работает.

В log4net я могу использовать пользовательский AdoNetAppender и извлеките соответствующие фрагменты строки подключения самостоятельно.Есть ли способ настроить цель базы данных NLog, чтобы я мог передать строку подключения в соответствующем стиле?

Ответы [ 5 ]

7 голосов
/ 08 ноября 2013

Эту проблему легко решить, настроив цель ведения журнала в коде:

    private DatabaseTarget CreateDatabaseTarget()
    {
        var entityFrameworkConnection = ConfigurationManager.ConnectionStrings["MyEntities"].ConnectionString;
        var builder = new EntityConnectionStringBuilder(entityFrameworkConnection);
        var connectionString = builder.ProviderConnectionString;

        var target = new DatabaseTarget()
        {
            ConnectionString = connectionString,
            CommandText = @"insert into Log ([DateTime], [Message]) values (@dateTime, @message);",
            Parameters = {
                new DatabaseParameterInfo("@dateTime", new NLog.Layouts.SimpleLayout("${date}")), 
                new DatabaseParameterInfo("@message", new NLog.Layouts.SimpleLayout("${message}")), 
           }
        };
        return target;
    }

Затем вы можете зарегистрировать его в своей конфигурации NLog:

var target = CreateDatabaseTarget();
LogManager.Configuration.AddTarget("databaseTarget", CreateDatabaseTarget());
LogManager.Configuration.LoggingRules.Add(new NLog.Config.LoggingRule("*", LogLevel.Warn, target));

Но если вы согласны с некоторыми зависимостями Nuget или хотите получить более полное решение, вы можете взглянуть на NLog.Mvc и NLog.EntityFramework репозитории, которые оба доступны пакеты nuget ...

5 голосов
/ 05 февраля 2012

Нет способа настроить встроенный DatabaseTarget, потому что это sealed. И нет никаких других точек расширения, потому что DatabaseTarget.InitializeTarget() всегда будет генерировать исключение, потому что он не может создать DbProviderFactory форму EF providerName="System.Data.EntityClient"

Таким образом, с текущей версией NLog 2.0.0.0 вам понадобятся следующие опции:

  1. Вы можете продублировать строку подключения или использовать DatabaseTarget Атрибуты конфигурации БД.
  2. Вы можете написать свою собственную пользовательскую цель в основном с нуля.
  3. Вы можете отправить запрос на функцию и подождать, пока он не будет реализован.
1 голос
/ 06 февраля 2019

В NLog 4.5 добавлена ​​поддержка парсинга строк соединений из Entity Framework, поэтому их можно использовать напрямую:

https://github.com/NLog/NLog/pull/2510

Также NLog DatabaseTarget больше не запечатывается, поэтому, если требуется специальная обработка, можно также сделать это.

Обычный способ сделать специальную логику синтаксического анализа / поиска - зарегистрировать пользовательский компоновщик и ссылаться на него в ConnectionString-Layout:

https://github.com/NLog/NLog/wiki/How-to-write-a-custom-layout-renderer

1 голос
/ 29 сентября 2015

Способ получения обычной строки подключения из DbContext заключается в следующем:

context.Database.Connection.ConnectionString

Предполагая, что у вас есть строка подключения в соответствующем формате, я думаю, проще настроить цель следующим образом:

1) определите цель в вашей конфигурации

 <target name="database" type="Database" connectionString="${gdc:myConnectionString}">
    <commandText>
      ...
    </commandText>

2) установите строку подключения во время выполнения

GlobalDiagnosticsContext.Set("myConnectionString", connectionString);

Таким образом, вы не будете жестко кодировать цель БДповедение.

0 голосов
/ 06 февраля 2019

Добавить переменную в файл NLog.config

<variable name="connectionStringNLog" value="" />

и затем ссылка на эту переменную в целевом элементе

<target name="my-db"
        xsi:type="Database"
        dbProvider="System.Data.SqlClient"        
        connectionString="${var:connectionStringNLog}"
        commandType="StoredProcedure"
        commandText="[dbo].[LogEntryInsert]">

и затем в вашем файле contextfactory c # добавьте эту строку, чтобы назначить значение строки подключения, независимо от того, исходит ли оно из другого файла конфигурации или хранилища ключей:

LogManager.Configuration.Variables["connectionStringNLog"] = conn.ConnectionString;
...