背景
我有一个用 asp.net core v2.2 编写的 Web 应用程序。我使用 NLog 作为我的第 3 方记录器,每次出现应用程序错误时它都会向我发送电子邮件,效果很好。
<targets>
<!--eg email on error -->
<target xsi:type="Mail"
name="emailnotify"
header="An Error has been reported By foo.com (${machinename}) ${newline} "
layout="${longdate} ${level:uppercase=true:padding=5} - ${logger:shortName=true} - ${message} ${exception:format=tostring} ${newline}"
html="true"
addNewLines="true"
replaceNewlineWithBrTagInHtml="true"
subject="Error on foo.com (${machinename})"
to="<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="bcdad3d3fcdad3d392dfd3d1" rel="noreferrer noopener nofollow">[email protected]</a>"
from="<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="75131a1a35131a1a5b161a18" rel="noreferrer noopener nofollow">[email protected]</a>"
secureSocketOption="StartTls"
smtpAuthentication="basic"
smtpServer="${environment:EmailConfigNlogSMTPServer}"
smtpPort="25"
smtpusername="${environment:EmailConfigNlogSMTPUsername}"
smtppassword="${environment:EmailConfigNlogSMTPPassword}" />
<!-- set up a blackhole log catcher -->
<target xsi:type="Null" name="blackhole" />
</targets>
<rules>
<!-- Skip Microsoft logs and so log only own logs-->
<logger name="Microsoft.*" level="Info" writeTo="blackhole" final="true" />
<!-- Send errors via emailnotify target -->
<logger name="*" minlevel="Error" writeTo="emailnotify" final="true" />
</rules>
但是,有时在我有机会解决问题之前,可能会在短时间内连续收到大量电子邮件,让我感觉自己受到了“垃圾邮件”。
- 一个例子可能是在极少数情况下,例如我的应用程序的第 3 方搜索引擎出现故障。此时,每个在网站上进行搜索的用户都会生成错误,从而可能产生大量电子邮件。
- 另一个例子是,当公司收集网站技术统计数据或只是简单的狡猾请求时,就会出现推测性 404 错误。即/bitcoin/xxx 或/shop/xxx 或 git/.head/xxx。
从历史上看,我在收到的一些 404 中使用过“过滤器”功能,并设置了一些。请参阅下面的示例。但是,在批量格式中,我希望收到有关所有 404 或 500 的通知。我认为尝试过滤掉看起来不相关的内容不是一个好主意,因为您可能会开始错过关键信息,例如黑客尝试、SQL 注入(inject)攻击或应用程序嗅探:
<filters>
<when condition="contains('${message}','.php')" action="Ignore" />
<when condition="contains('${message}','wp-includes')" action="Ignore" />
<when condition="contains('${message}','wordpress')" action="Ignore" />
<when condition="contains('${message}','downloader')" action="Ignore" />
</filters>
</logger>
要求
我想在我的应用程序日志记录中引入以下逻辑:
- 当发生第一个 500 个类型错误时(即在网站上执行搜索时出错、访问数据库时出错),我会收到电子邮件通知,以便我在应用程序第一次出现初始错误时立即知道
- 在出现初始错误后批量通知连续 500 个错误,以便我知道何时会发生此错误,但它不会继续向我发送“垃圾邮件”。
- 批量通知所有 404、405 错误
这些批量电子邮件会在 50 个错误后通知我,或者每天一次,以先到者为准。
理想情况下,我希望批量电子邮件的格式为:
批量电子邮件
主题:500 个错误 (13) | 404错误(2)
表格格式的正文:
500 Errors (13)
-----------------------------------------------------
| When | Message |
-----------------------------------------------------
| 2019-11-13 11:10:29 | Website search engine down |
-----------------------------------------------------
| 2019-11-13 11:10:30 | Website search engine down |
-----------------------------------------------------
| 2019-11-13 11:10:31 | Website search engine down |
-----------------------------------------------------
| 2019-11-13 11:10:32 | Website search engine down |
-----------------------------------------------------
| 2019-11-13 11:10:33 | Website search engine down |
-----------------------------------------------------
| 2019-11-13 11:10:34 | Website search engine down |
-----------------------------------------------------
| 2019-11-13 11:10:35 | Website search engine down |
-----------------------------------------------------
| 2019-11-13 11:11:01 | Login failed for user foo |
-----------------------------------------------------
| 2019-11-13 11:11:01 | Login failed for user foo |
-----------------------------------------------------
| 2019-11-13 11:11:01 | Login failed for user foo |
-----------------------------------------------------
| 2019-11-13 11:11:02 | Login failed for user foo |
-----------------------------------------------------
| 2019-11-13 11:11:02 | Login failed for user foo |
-----------------------------------------------------
| 2019-11-13 11:11:02 | Login failed for user foo |
-----------------------------------------------------
404 Errors (2)
-----------------------------------------------------
| When | Message |
-----------------------------------------------------
| 2019-11-13 11:10:45 | /bitcoin not found |
-----------------------------------------------------
| 2019-11-13 11:10:57 | /shop not found |
-----------------------------------------------------
或者,我很乐意为 500、404 或 405 提供单独的批量电子邮件。
在上面的批量电子邮件示例中,应用程序会立即通过两封单独的电子邮件通知我存在问题
- 网站搜索引擎关闭
- 用户无法访问 SQL 数据库
然后在遇到 50 个错误或每天一次后,发送批量电子邮件。
问题
仅使用 NLog 配置就可以实现我的要求吗?
我可以看到如何使用 NLog 的 buffer wrapper 执行批量通知配置,尽管我认为不可能以我理想的表格格式输出。
<target xsi:type="BufferingWrapper"
name="bulkemailnotify"
bufferSize="50"
flushTimeout="86400000"
slidingTimeout="False"
overflowAction="Flush">
<target xsi:type="emailnotify" />
</target>
如果没有,它会考虑以下其中一项吗?
理想情况下,我会继续使用 NLog,并且只会添加自定义记录器作为最后的手段。
最佳答案
假设 ${aspnet-response-statuscode}
是返回 HTTP 状态代码的:
那么我们可以有以下两个目标:
- 具有第一个错误的即时邮件目标(通过第一个事件即时触发,并等待 5 分钟后再触发)
- 包含所有错误的批量邮件目标(所有事件在 5 分钟后触发)
那么你可能会这样做:
<targets async="true">
<target xsi:type="SplitGroup" name="special-mail">
<target xsi:type="FilteringWrapper" name="filter-mail">
<filter type="whenRepeated" layout="${aspnet-response-statuscode}" timeoutSeconds="300" action="Ignore" />
<target xsi:type="Mail" name="instant-mail">
<header>Instant Error Report</header>
</target>
</target>
<target xsi:type="BufferingWrapper" name="buffer-mail" flushTimeout="300000">
<target xsi:type="Mail" name="bulk-mail">
<header>Bulk Error Report</header>
</target>
</target>
</target>
</targets>
<rules>
<logger name="Microsoft.*" maxlevel="Info" final="true" />
<logger name="*" minlevel="Error" writeTo="special-mail" final="true" />
</rules>
不太熟悉邮件目标布局(页眉+正文+页脚)以及制作美观的 html 电子邮件。但您可能可以从互联网上窃取一些东西。
关于asp.net-core - NLog 初始发送和多次批量发送电子邮件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58839987/