ASP.NET Core 2.0中NLog无法向邮件目标写入日志问题求助
之前用log4net转NLog,文件和数据库日志正常但邮件发不出去,这种情况在对接内部SMTP时挺常见的,咱们一步步来排查:
1. 先核对NLog邮件目标的核心配置
先确保你的NLog.config里的邮件目标参数没写错,内部SMTP通常有特定要求:
- 确认
smtpServer是公司内部SMTP的正确地址(比如smtp.yourcorp.internal),别把域名或IP打错了 - 检查
smtpPort:内部SMTP常用25端口,但有些会用587(TLS)或465(SSL),不确定的话直接问IT部门 - 如果内部SMTP需要认证,记得加上
enableSsl(根据实际情况设true/false),还有username和password,域账号的话格式一般是CORP\username:
<target xsi:type="Mail" name="mailTarget" smtpServer="smtp.yourcorp.internal" smtpPort="25" enableSsl="false" from="app-logs@yourcorp.com" to="dev-team@yourcorp.com" subject="ASP.NET Core 应用错误日志" body="${longdate} ${level} ${message} ${exception:format=ToString}" username="CORP\your-smtp-account" password="your-smtp-password" />
有些内部SMTP允许匿名转发,但如果是权限管控严格的,必须用指定账号。
2. 开启NLog内部日志抓错误细节
NLog的内部日志能直接帮你看到邮件发送时的具体异常,比如连接失败、认证错误。在NLog.config里加这段开启:
<nlog internalLogLevel="Debug" internalLogFile="nlog-internal.log"> <!-- 你的目标和规则配置 --> </nlog>
触发日志后打开nlog-internal.log,找带MailTarget的条目,比如有没有Failed to send mail的报错,里面的SmtpException会告诉你到底是哪出问题了,这是定位问题的关键。
3. 先排除SMTP服务器本身的问题
先确认不是网络或SMTP服务器的锅,在应用服务器上用工具测试:
- 用
telnet smtp.yourcorp.internal 25测试能不能连通端口,连不通的话就是防火墙或服务器权限的问题 - 用PowerShell直接发邮件,排除NLog的影响:
$smtpServer = "smtp.yourcorp.internal" $smtpPort = 25 $from = "test@yourcorp.com" $to = "your-email@yourcorp.com" $subject = "SMTP连通测试" $body = "这是从服务器发的测试邮件" $smtp = New-Object Net.Mail.SmtpClient($smtpServer, $smtpPort) # 如果需要认证就加下面两行 # $smtp.Credentials = New-Object System.Net.NetworkCredential("CORP\username", "password") # $smtp.EnableSsl = $true $smtp.Send($from, $to, $subject, $body)
如果这个脚本也发不出,直接找IT部门确认:应用服务器的IP是不是在SMTP的允许转发列表里,有没有端口被防火墙拦截。
4. 检查NLog的日志路由规则
别漏了确认日志规则有没有把日志导向邮件目标,比如只发送Error及以上级别的日志:
<rules> <logger name="*" minlevel="Error" writeTo="mailTarget" /> <!-- 你的文件、数据库日志规则 --> </rules>
如果规则里的级别设成了Fatal,而你触发的是Error日志,那邮件肯定不会发。
5. 测试禁用异步发送(可选)
NLog默认异步发邮件,有时候异步队列出问题会吞掉异常,暂时禁用异步试试:
<target xsi:type="Mail" name="mailTarget" async="false" <!-- 其他参数 --> />
禁用后能发的话,就是异步队列的配置问题,比如队列满了或者有未处理的异常。
6. 强制指定TLS版本(针对.NET Core)
NLog的MailTarget底层用System.Net.Mail.SmtpClient,有些内部SMTP只支持TLS 1.2,在Program.cs里加一行强制设置:
// 在应用启动代码里添加 System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
要是以上步骤都试过还是不行,把NLog内部日志里的错误信息贴出来,或者PowerShell测试的结果,就能更精准定位问题了。
内容的提问来源于stack exchange,提问作者Babu Mannavalappil

