【问题标题】:NLog: custom installer programNLog:自定义安装程序
【发布时间】:2016-07-26 15:23:15
【问题描述】:

我的任务是编写一个 c# 表单应用程序来:

  • 显示可安装 NLog 的可用网站的 DDL(基于我们的内部标准)
  • 安装支持 NLog 所需的文件 我有具有 NLog 功能的工作站点(我没有编写),我将其用作开始的基础。 Global.asax 和 App_Code/LogManager.vb 之间存在一些连接/交互,以将错误引导到 NLog。我没有写那部分,所以我认为这可能是问题所在,因为我不知道它们如何交互......

这是供我们的实施工程师用作部署工具的。

(注意:此应用程序是 C#,但目标网站始终是 VB 我们的生态系统)

正在复制的文件:

  • bin/NLog.dll
  • bin/NLog.Extended.dll
  • Global.asax
  • NLog.config
  • App_Code/LogManager.vb

在我们的 Global.asax 中,我们正在捕获如下错误:

Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)
    ' Code that runs when an unhandled error occurs
    Dim lastException As Exception = Server.GetLastError()
    HandleError(lastException)       
End Sub
 Public Shared Sub HandleError(ex As Exception)
    'Honor the config setting for whether we should do the logging. 

    Dim hostId As String = ""

    If HttpContext.Current IsNot Nothing AndAlso HttpContext.Current.Request IsNot Nothing Then
        hostId = " (" + HttpContext.Current.Request.Url.Host + ")"
    End If

    If ex Is Nothing Then
        'OrElse request.Url.Host.ToLower = "localhost" Then
        Return
    End If

    If ShouldLogError(ex) Then
        Dim LogManager As New LogManager()

        LogManager.Logger.LogError("Global Exception",ex)

    End If
End Sub

Protected Shared Function ShouldLogError(ex As Exception) As Boolean
    If TypeOf ex Is System.Web.HttpRequestValidationException Then
        Return False
    End If

    If TypeOf ex Is HttpException Then
        Dim exHttp As HttpException = DirectCast(ex, HttpException)
        Select Case exHttp.GetHttpCode()
            Case 404
                'File Not Found
                Return False
        End Select
    End If

    If TypeOf ex Is System.IO.FileNotFoundException Then
        Return False
    End If

    If TypeOf ex.InnerException Is System.IO.FileNotFoundException Then
        Return False
    End If

    If TypeOf ex Is System.Reflection.TargetInvocationException OrElse TypeOf ex Is System.FormatException OrElse (TypeOf ex Is HttpException AndAlso ex.Message.Contains("Invalid viewstate.")) OrElse TypeOf ex Is System.Security.Cryptography.CryptographicException Then
        If HttpContext.Current.Request.Url.AbsolutePath.EndsWith("ScriptResource.axd", StringComparison.OrdinalIgnoreCase) OrElse HttpContext.Current.Request.Url.AbsolutePath.EndsWith("WebResource.axd", StringComparison.OrdinalIgnoreCase) Then
            Return False
        End If
    End If

    Return True
End Function

在 LogManager.vb 中:

Public Class LogManager

Private _Logger As ILogger

Public Sub New()

End Sub

Public ReadOnly Property Logger As ILogger
    Get
        If _Logger Is Nothing Then
            _Logger = New LoggerFactory().CreateLoggerNlog("Website")
        End If

        Return _Logger

    End Get
End Property
End Class

和 NLog.config:

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<extensions>
  <add assembly="OURDOMAINlibrary"/>
  <!--<add assembly="NLog.Extended"/>-->
</extensions>
<targets async="false">
  <target xsi:type="Console" name="debugConsole" layout="${VnEventId:brackets=true} ${uppercase:${level}} ${LoggerFriendly} ${message} "/>
</targets>
<targets async="true">
  <target xsi:type="File" name="debugFile" createDirs="true" fileName="c:/Vendornet/Log/${iis-site-name}}/${iis-site-name}_${shortdate}.log" layout="${longdate} ${VnEventId:brackets=true} ${uppercase:${level}} ${LoggerFriendly} ${message}"/>
  <!-- Alter the smtpServer and to attributes only. For information regarding the ${FatalEmail} tag, see 
                 the documentation provided with this project
        -->
  <target name="mail" xsi:type="Mail" html="true" replaceNewlineWithBrTagInHtml="true" smtpServer="OURDOMAIN" smtpAuthentication="None" to="${FatalEmail:DL-OURDOMAIN-ImpDev@OURDOMAIN.com;me@OURDOMAIN.com}" from="${machinename}@OURDOMAIN.com" subject="${iis-site-name} - ${processname} has FAILED on ${machinename}." body="${message}"/>
  <!-- The Webservice Target Below should not be modified except for the url attribute. To disable this target
             set the minlevel in the Rules section to Off. Otherwise set it to Trace or higher
        -->
  <target type="WebService" name="vnLogApi" url="http://OURDOMAIN/api/log" protocol="HttpPost" encoding="UTF-8">
    <parameter name="time_stamp" type="System.String" layout="${date}"/>
    <parameter name="level" type="System.String" layout="${level}"/>
    <parameter name="logger" type="System.String" layout="${logger}"/>
    <parameter name="userName" type="System.String" layout="${identity}"/>
    <parameter name="url" type="System.String" layout="${aspnet-request:serverVariable=Url}"/>
    <parameter name="machineName" type="System.String" layout="${machinename}"/>
    <parameter name="sessionId" type="System.String" layout="${aspnet-sessionid}"/>
    <parameter name="threadId" type="System.String" layout="${threadid}"/>
    <parameter name="referrer" type="System.String" layout="${aspnet-request:serverVariable=HTTP_REFERER}"/>
    <parameter name="userAgent" type="System.String" layout="${aspnet-request:serverVariable=HTTP_USER_AGENT}"/>
    <parameter name="code" type="System.String" layout="${CUSTOMEventId}"/>
    <parameter name="message" type="System.String" layout="${message}"/>
    <parameter name="version" type="System.String" layout=""/>
    <parameter name="exception" type="System.String" layout="${exception}"/>
    <parameter name="stackTrace" type="System.String" layout="${stacktrace}"/>
    <parameter name="clientName" type="System.String" layout="${iis-site-name}"/>
    <parameter name="fileName" type="System.String" layout="${iis-site-name} ${date}"/>
  </target>
</targets>
<rules>
  <logger name="*" minlevel="Trace" writeTo="debugConsole"/>
  <logger name="*" minlevel="Trace" writeTo="debugFile"/>
  <!-- SET TO Trace or Higher Once LogAPI is available for this server -->
  <logger name="*" minlevel="Trace" writeTo="vnLogApi"/>
  <!-- THIS LINE SHOULD NOT BE MODIFIED -->
  <logger name="*" minlevel="Fatal" writeTo="mail"/>
</rules>

因此,即使使用最精简的 NLog.config,它也不会输出任何内容...尝试了一个简单的日志文件、webservice 邮件...什么也没有。我尝试了几个地方来触发错误,但命名一个 var 错误,缺少一个 conn.open 等,但无济于事......

我还尝试绕过对“ShouldLogError()”的检查,以确保它会触发但不会执行。

需要什么其他文件或调整才能让 NLog 以这种方式工作?

【问题讨论】:

    标签: c# asp.net vb.net winforms nlog


    【解决方案1】:

    你的配置有错误,应该只有一个&lt;targets&gt;(在你的情况下有多个&lt;target&gt;s)&lt;nlog&gt; 也没有关闭 - 但这可能是复制粘贴错误。

    应该是:

    <?xml version="1.0" encoding="utf-8" ?>
    <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <extensions>
        <add assembly="OURDOMAINlibrary"/>
        <!--<add assembly="NLog.Extended"/>-->
      </extensions>
      <targets async="true">
        <target xsi:type="Console" name="debugConsole" layout="${VnEventId:brackets=true} ${uppercase:${level}} ${LoggerFriendly} ${message} "/>
        <target xsi:type="File" name="debugFile" createDirs="true" fileName="c:/Vendornet/Log/${iis-site-name}}/${iis-site-name}_${shortdate}.log" layout="${longdate} ${VnEventId:brackets=true} ${uppercase:${level}} ${LoggerFriendly} ${message}"/>
        <!-- Alter the smtpServer and to attributes only. For information regarding the ${FatalEmail} tag, see 
                     the documentation provided with this project
            -->
        <target name="mail" xsi:type="Mail" html="true" replaceNewlineWithBrTagInHtml="true" smtpServer="OURDOMAIN" smtpAuthentication="None" to="${FatalEmail:DL-OURDOMAIN-ImpDev@OURDOMAIN.com;me@OURDOMAIN.com}" from="${machinename}@OURDOMAIN.com" subject="${iis-site-name} - ${processname} has FAILED on ${machinename}." body="${message}"/>
        <!-- The Webservice Target Below should not be modified except for the url attribute. To disable this target
                 set the minlevel in the Rules section to Off. Otherwise set it to Trace or higher
            -->
        <target type="WebService" name="vnLogApi" url="http://OURDOMAIN/api/log" protocol="HttpPost" encoding="UTF-8">
          <parameter name="time_stamp" type="System.String" layout="${date}"/>
          <parameter name="level" type="System.String" layout="${level}"/>
          <parameter name="logger" type="System.String" layout="${logger}"/>
          <parameter name="userName" type="System.String" layout="${identity}"/>
          <parameter name="url" type="System.String" layout="${aspnet-request:serverVariable=Url}"/>
          <parameter name="machineName" type="System.String" layout="${machinename}"/>
          <parameter name="sessionId" type="System.String" layout="${aspnet-sessionid}"/>
          <parameter name="threadId" type="System.String" layout="${threadid}"/>
          <parameter name="referrer" type="System.String" layout="${aspnet-request:serverVariable=HTTP_REFERER}"/>
          <parameter name="userAgent" type="System.String" layout="${aspnet-request:serverVariable=HTTP_USER_AGENT}"/>
          <parameter name="code" type="System.String" layout="${CUSTOMEventId}"/>
          <parameter name="message" type="System.String" layout="${message}"/>
          <parameter name="version" type="System.String" layout=""/>
          <parameter name="exception" type="System.String" layout="${exception}"/>
          <parameter name="stackTrace" type="System.String" layout="${stacktrace}"/>
          <parameter name="clientName" type="System.String" layout="${iis-site-name}"/>
          <parameter name="fileName" type="System.String" layout="${iis-site-name} ${date}"/>
        </target>
      </targets>
      <rules>
        <logger name="*" minlevel="Trace" writeTo="debugConsole"/>
        <logger name="*" minlevel="Trace" writeTo="debugFile"/>
        <!-- SET TO Trace or Higher Once LogAPI is available for this server -->
        <logger name="*" minlevel="Trace" writeTo="vnLogApi"/>
        <!-- THIS LINE SHOULD NOT BE MODIFIED -->
        <logger name="*" minlevel="Fatal" writeTo="mail"/>
      </rules>
    </nlog>
    

    请记住,您只能使用 async 属性来所有目标。如果你只需要一个目标异步,你应该使用异步包装器:

    <targets>
       <target name="target2" xsi:type="AsyncWrapper">
         <target name ="target1" xsi:type="File"
                    fileName="c:/temp/test.log" layout="${message}"
                    keepFileOpen="true" />
       </target>
       <rules>
         <logger name="*" minlevel="Info" writeTo="target2"/>
       </rules>
    </targets> 
    

    请参阅AsyncWrapper target docs

    如果您仍然遇到问题,请启用并检查internal log

    【讨论】:

    • 内部日志根本不起作用,仅供参考。不知道为什么...原来问题出在某些布局上。我们正在包装 NLog,但不是 NLog.web,一些布局依赖于它。此外,您显然可以有两个 节点,只要一个是异步的,一个是同步的。现在是这样的
    • 检查了源代码 - 确实,两个 &lt;targets&gt; 可以工作。 :)
    • 感谢您的跟进:)
    【解决方案2】:

    显然,我之前的那个人将一些 NLog 写入了我们的自定义 dll 之一,但没有写入 NLog.web,这是某些布局(如 {iis-site-name})所必需的。删除那些修复它:

    【讨论】:

    • 对于{iis-site-name},您确实需要NLog.Web,自NLog 4 以来它已被移至单独的包中。请参阅NLog 4 release postlayout renderer overview。注意:NLog.Web 是一个官方的 NLog 包
    • 谢谢。这最初是在版本 3x 中创建的。因此有些混乱。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-22
    相关资源
    最近更新 更多