Azure网站启用异步日志后大量日志丢失的技术求助
我之前在Azure环境下用NLog异步写Blob日志时也踩过类似的坑,结合你的场景——同步日志正常、切换异步后大量丢失的情况,大概率是这几个细节没处理好,给你几个具体的排查和修复方向:
确保应用优雅关闭NLog
虽然你设置了overflowAction="Block",但如果应用在 shutdown 时没有主动通知NLog处理完队列里的日志,未提交的异步日志会直接丢失。一定要在应用终止时调用LogManager.Shutdown():比如在ASP.NET中,你可以在Global.asax的Application_End方法里添加,或者在ASP.NET Core的主机生命周期事件中注册停止逻辑。这个方法会等待异步队列中的所有日志都处理完成后再退出,避免丢日志。补全异步Wrapper的批量提交配置
你的配置里batchSi...没写完,异步Wrapper的batchSize和batchTimeout是关键参数:- 如果
batchSize设得太大,日志要凑够数量才会提交,一旦应用突然终止,没凑够批量的日志就会丢失; - 如果
batchTimeout太长,同样会导致短时间内的日志堆积在队列里,遇到重启就丢。
建议设置合理的数值,比如:
<target name="asyncTrace" xsi:type="AsyncWrapper" overflowAction="Block" queueLimit="200000" batchSize="200" batchTimeout="500"> <target xsi:type="Trace" name="originalTrace" /> <!-- 你的原始Trace目标配置 --> </target>这样既保证了批量提交的性能,又能让未凑够批量的日志在500ms后自动提交,减少丢失风险。
- 如果
排查Trace目标与Azure诊断日志的兼容性
你是通过NLog写Trace,再由Azure诊断日志转存到Blob,中间多了一层TraceListener。异步写入时可能存在TraceListener的线程安全问题,或者Trace源配置不匹配导致日志没被捕获。
一个更稳定的方案是绕过Trace层,直接用NLog的AzureBlobStorage目标写Blob,这样减少中间环节,异步逻辑也更可控。开启NLog内部日志排查问题
如果还是找不到原因,开启NLog的内部日志,它会记录异步队列的状态、是否有溢出、提交失败等细节:<nlog internalLogLevel="Debug" internalLogFile="D:\home\site\wwwroot\nlog-internal.log"> <!-- 你的现有NLog配置 --> </nlog>在Azure App Service中,你可以通过Kudu控制台查看这个日志文件,里面的错误信息会帮你定位到底是队列溢出、提交失败还是其他问题。
调整队列大小并监控内存
queueLimit="200000"看起来很大,但如果单条日志体积大,队列会占用大量内存,当应用内存不足时,可能会被CLR强制回收或应用崩溃,导致队列丢失。建议结合应用的内存使用情况,适当调整队列大小,避免内存过载。
内容的提问来源于stack exchange,提问作者Rousonur Jaman

