.net – 使用ELK堆栈进行应用程序日志记录

使用NLog和Elasticsearch target将日志转发到AWS Elasticsearch as a Service集群,以便在Kibana中进行可视化.

这很好但我担心由于ES群集可用性而在生产中使用它,以及当使用elasticsearch-net client通过HTTP发送日志时群集故障转移的影响.

我正在考虑为NLog使用不同的目标,将日志发送到更可靠的目的地(文件,S3?),然后让其他东西(Logstash,AWS Lambda)接收它们并将它们发送到ES,这样可以最大限度地降低风险申请本身.

想听听你的想法

UPDATE

主要关注的是应用程序可用性和防止丢失日志使用辅助目标.

使用最新的NLog和throwExceptions设置为false,此时不使用异步目标,但考虑到这一点,因为我们有很多异步代码.

为了给出更多的上下文,“app”是一组API(WebAPI和WCF),它们的速度为10-15K RPM.

脚本

请求进来,ES群集不可用.

案例1 – 没有异步目标的NLog

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
        autoReload="true"
        throwExceptions="false"
        internalLogLevel="Off"
        internalLogFile="c:\temp\nlog-internal.log">

    <targets>
      <target name="elastic"
              xsi:type="BufferingWrapper"
              flushTimeout="5000">
        <target xsi:type="ElasticSearch"
                layout="${logger} | ${threadid} | ${message}"
                index="logstash-${date:format=yyyy.MM.dd}"
                includeAllProperties="true"
                uri="...">

          <field name="user"
                 layout="${windows-identity:userName=True:domain=False}"/>
          <field name="host"
                 layout="${machinename}"/>
          <field name="number"
                 layout="1"
                 layoutType="System.Int32"/>

        </target>
      </target>
    </targets>
    <rules>
      <logger name="*"
              minlevel="Debug"
              writeTo="elastic" />
    </rules>
  </nlog>

问:

>当无法到达目标时主线程会发生什么?

案例2 – 具有异步目标的NLog

使用带有queueLimit =“10000”的弹性搜索目标的异步包装程序batchSize =“100”

问:

>是另一个线程[B]创建的?
>后续请求会重用线程[B]并对日志记录请求进行排队吗?
>达到queueLimit时会发生什么?
>将启动其他线程[B1 … Bn]吗? (这会泛滥连接池)

最佳答案
好问题.

没有什么可担心的,但正确配置NLog很重要.

不确定什么应该是可靠的,运行程序或不丢失日志消息,所以对于这些情况:

>如果您害怕丢失一些日志消息

>写入多个目标(来自NLog),例如文件和弹性搜索.
>可选,使用fallbackgroupwrapper(如果写入目标时出错)
>如果启用了异步,则默认启用check the overflow/queue settings – discard(以防止CPU或内存过载)

>如果您担心日志记录可能会破坏您的应用程序:

>使用最新的稳定版NLog
>不要启用throwExceptions(默认情况下禁用)
>如果启用异步,则会在另一个线程中将错误写入目标,因此无法破坏您的应用.
>同样在使用async时,check the overflow and queue settings

更新

情况1,

what happens with the main thread when target can’t be reached?

没有.主要将消息排入缓冲区.另一个(Timer)线程正在处理这些消息.如果失败,并且未启用throwException,则只会将错误写入internalLog(启用时).将捕获所有异常.写入目标失败时,您将丢失消息.

案例2,

is another thread[B] created ?

将创建一个Timer.这将创建一个用于处理消息的线程.

will subsequent requests reuse thread [B] and queue the logging requests?

是的,但不保证它会是同一个线程.计时器将从池中创建一个线程.注意:只有一个线程会同时存活.

what happens when the queueLimit is reached?

取决于您的配置.默认情况下,它将默认丢弃,如上所述.请参阅check the overflow/queue settings.就内存和CPU而言,这是最安全的选项.您可以选择丢弃,阻止(停止主线程)或增加队列(通过了解内存使用情况).

will additional threads [B1 … Bn] be started? (this will flood connection pool)

1号计时器,1个线程池.有关详细信息,请查看MSDN page for Timerreference source.

转载注明原文:.net – 使用ELK堆栈进行应用程序日志记录 - 代码日志