我有一个将dll加载到单独的appdomain中的服务(appdomain是必需的,因为dll正在加载一个动态生成的程序集,并且需要能够卸载它们)
如何复制nlog配置以使新的appdomain使用相同的设置?
另一个复杂之处在于,我在程序开始时使用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>发布于 2011-03-18 11:02:48
我不知道是否有更自动的方法让每个AppDomain使用相同的配置信息,但你可以在这篇文章中使用这个技术:
Most useful NLog configurations
通过XML以编程方式设置配置。对于您加载的每个AppDomain,您可以读取NLog配置文件,然后在新的AppDomain中设置NLog上的XML。
将全局值存储到新的AppDomain中的一种可能的解决方案是使用CallContext.LogicalSetData存储它们。这些值将流向新的AppDomain。使用CallContext.LogicalGetData编写自定义LayoutRenderer以获取这些值。LayoutRenderer非常容易编写。
请参阅这篇文章,了解如何编写自定义LayoutRenderer来根据键查找值(就像GDC一样)。对于内部,只需使用CallContext.LogicalGetData来检索值:
Custom log4net property PatternLayoutConverter (with index)
请参阅Jeffrey Richter关于使用CallContext的这篇博客文章:
http://www.wintellect.com/CS/blogs/jeffreyr/archive/2010/09/27/logical-call-context-flowing-data-across-threads-appdomains-and-processes.aspx
发布于 2012-08-08 04:42:52
我刚刚做了一件非常类似的事情,我发现每个子AppDomain中的静态成员NLog.LogManager.Configuration一开始都与父AppDomain中的成员具有相同的值。我不确定它最终是从app.config重新读取值,还是直接从父AppDomain复制静态成员。
此外,我最终使用CallContext来过滤所有符合特定条件(例如,导致程序运行的激励请求ID )的日志消息(无论记录器名称如何),并将它们分组到内存中的日志目标。
https://stackoverflow.com/questions/5346336
复制相似问题