Конфигурация NLog через домены - PullRequest
2 голосов
/ 18 марта 2011

У меня есть служба, которая загружает dll в отдельный домен приложения (домен приложения необходим, потому что dll загружает динамически генерируемую сборку и должна иметь возможность выгрузить их)

Как скопировать конфигурацию nlog, чтобы новый домен приложения использовал те же настройки?

Еще одна сложность заключается в том, что я настраиваю параметры ведения журнала, используя GlobalDiagnosticsContext в начале программы. Есть ли какая-либо опция, кроме необходимости устанавливать их заново в каждом домене приложения?

static void Main()
{
    // Setup NLog variables
    GlobalDiagnosticsContext.Set("ConnectionString", @"...");
    GlobalDiagnosticsContext.Set("ApplicationName", @"appName");

    // ... loads appdomain and does logging from the new appdomain

Это мой конфигурационный файл:

<?xml version="1.0" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

  <variable name="TextErrorLayout" value ="${gdc:item=ApplicationName} ${date:format=yyyy-MM-dd HH\:mm\:ss.fff}${newline}
Level: ${level}${newline}
Description: ${message}${newline}
Machine: ${machinename}${newline}
User: ${windows-identity}${newline}
Process: ${processname}${newline}
WorkingDir: ${basedir}${newline}
Exception: ${exception:format=tostring}${newline}
DetailedMessage: ${event-context:item=Details}${newline}"/>

  <targets async="true">
    <target name="LogMill" xsi:type="FallbackGroup">
      <target xsi:type="Database"
              connectionString="${gdc:item=ConnectionString}"
              commandText="exec dbo.Usp_Log_CreateWithExtended @applicationName, @logLevel, @entryDate, @description, @machineName, @userName, @assembly, @workingDirectory, @exception, @detailedMessage">
        <dbProvider>mssql</dbProvider>
        <parameter name="@applicationName" layout="${gdc:item=ApplicationName}"/>
        <parameter name="@logLevel" layout="${level}"/>
        <parameter name="@entryDate" layout="${date:format=yyyy-MM-dd HH\:mm\:ss.fff}"/>
        <parameter name="@description" layout="${message}"/>
        <parameter name="@machineName" layout="${machinename}"/>
        <parameter name="@userName" layout="${windows-identity}"/>
        <parameter name="@assembly" layout="${processname}"/>
        <parameter name="@workingDirectory" layout="${basedir}"/>
        <parameter name="@exception" layout="${exception:format=tostring}"/>
        <parameter name="@detailedMessage" layout="${event-context:item=Details}"/>
      </target>
      <target xsi:type="File" fileName="LogMill-FailSafe.log" layout="${TextErrorLayout}"/>
    </target>

    <target name="EmailDevelopers" xsi:type="Mail"
            smtpServer="smtp.local"
            from="errors@email.com"
            to="email@email.com"
            subject="${gdc:item=ApplicationName} ${level} Error: ${message}"
            layout="${TextErrorLayout}"/>

    <target name="Console" xsi:type="ColoredConsole" layout="${date:format=yyyy-MM-dd HH\:mm\:ss.fff} ${message} ${exception:format=tostring}"/>
  </targets>

  <rules>
    <logger name="*" minlevel="Info" writeTo="LogMill" />
    <logger name="*" minlevel="Error" writeTo="EmailDevelopers" />
  </rules>
</nlog>

Ответы [ 2 ]

2 голосов
/ 18 марта 2011

Я не знаю, есть ли более автоматический способ заставить каждый AppDomain использовать одну и ту же информацию о конфигурации, но вы могли бы использовать метод в этом посте:

Наиболее полезныйКонфигурации NLog

Для настройки конфигурации программно через XML.Для каждого загружаемого вами домена приложения вы можете прочитать конфигурационный файл NLog, а затем установить XML для NLog в новом домене приложений.

Одним из возможных решений для получения ваших глобальных значений в новом домене приложений будет их хранение с использованием CallContext.LogicalSetData.Значения будут перенаправлены в новый домен приложений.Напишите пользовательский LayoutRenderer, чтобы получить значения, используя CallContext.LogicalGetData.LayoutRenderer довольно легко написать.

В этом посте приведен пример того, как написать собственный LayoutRenderer, который ищет значение на основе ключа (как в GDC).Для внутренних устройств просто используйте CallContext.LogicalGetData, чтобы получить значение:

Настраиваемое свойство log4net PatternLayoutConverter (с индексом)

См. Это сообщение в блоге Джеффри Рихтера об использованииCallContext:

http://www.wintellect.com/CS/blogs/jeffreyr/archive/2010/09/27/logical-call-context-flowing-data-across-threads-appdomains-and-processes.aspx

1 голос
/ 08 августа 2012

Я только что сделал что-то очень похожее, и обнаружил, что статический член NLog.LogManager.Configuration в каждом дочернем AppDomain начинался с того же значения, что и этот член в родительском AppDomain. Я не уверен, что это закончилось перечитывание значений из app.config или если статические члены копируются напрямую из родительского домена AppDomain.

Кроме того, в конечном итоге я использовал CallContext для фильтрации всех сообщений журнала (независимо от имени регистратора), соответствующих определенным критериям (например, идентификатору мотивационного запроса, который вызвал выполнение программы), и сгруппировал их в цель журнала в памяти ,

...