Ведение журнала приложений с помощью стека ELK

Использование NLog с целью Elasticsearch для пересылки журналов в кластер AWS Elasticsearch as a Service для визуализации в Kibana.

Это работает нормально, но я обеспокоен использованием этого в производстве из-за доступности кластера ES и влияния отработки отказа кластера, когда журналы отправляются с использованием клиент elasticsearch-net через HTTP.

Я рассматриваю возможность использования другой цели для NLog, которая отправляет журналы в более надежное место назначения (файл, S3?), а затем что-то еще (Logstash, AWS Lambda) собирает их и отправляет в ES, таким образом сводя к минимуму риски на само приложение.

Хотел бы услышать ваши мысли

ОБНОВЛЕНИЕ

Основной проблемой является доступность приложения, и для предотвращения отсутствия журналов используется вторичная цель.

Для использования последних NLog и throwExceptions установлено значение false и на данный момент не используются асинхронные цели, но учитывая это, поскольку у нас много асинхронного кода.

Чтобы дать немного больше контекста, «приложение» — это набор API (WebAPI и WCF), которые получают 10–15 тыс. об/мин.

Сценарий

Приходит запрос, а кластер 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>

Q:

  • что происходит с основным потоком, когда цель не может быть достигнута?

Вариант 2 — NLog с асинхронной целью

Использование асинхронной оболочки для цели elasticsearch с queueLimit="10000" batchSize="100"

Q:

  • создан еще один поток [B]?
  • будут ли последующие запросы повторно использовать поток [B] и ставить в очередь запросы на регистрацию?
  • что происходит, когда достигается ограничение очереди?
  • будут ли запущены дополнительные потоки [B1 ... Bn]? (это приведет к затоплению пула соединений)

person thedev    schedule 25.11.2016    source источник


Ответы (1)


Хороший вопрос.

В этом нет ничего страшного, но важна правильная настройка NLog.

Не уверен, что должно быть надежным, запускать программу или не терять сообщение журнала, поэтому для этих случаев:

  • Если вы боитесь, если вы потеряете некоторые сообщения журнала

    • Write to multiple targets (from NLog), e.g. File and Elasticsearch.
    • Необязательно, используйте fallbackgroupwrapper (на случай ошибки при записи в цель)
    • Если асинхронность включена, проверьте переполнение /queue settings - отбрасывание включено по умолчанию (для защиты от перегрузки процессора или памяти)
  • Если вы боитесь, что ведение журнала может сломать ваше приложение:

    • Use the latest stable version of NLog
    • Не включать throwExceptions (по умолчанию отключено)
    • Если вы включите async, ошибки записываются в цель в другом потоке, поэтому это не может сломать ваше приложение.
    • Также при использовании async проверьте переполнение и настройки очереди

Обновить

Случай 1,

что происходит с основным потоком, когда цель не может быть достигнута?

Ничего такого. Основной ставит сообщения в очередь в буфере. Другой (Timer) поток обрабатывает эти сообщения. Если это не удастся и throwException не будет включено, во внутренний журнал будут записаны только ошибки (если он включен). Все исключения будут перехвачены. Вы потеряете сообщение при сбое записи в цель.

Случай 2,

создан еще один поток [B]?

Один Timer будет быть создан. Это создаст поток для обработки сообщения.

будут ли последующие запросы повторно использовать поток [B] и ставить в очередь запросы на регистрацию?

Да, но нет гарантии, что это будет тот же поток. Таймер создаст поток из пула. NB: одновременно будет работать только один поток.

что происходит, когда достигается ограничение очереди?

Зависит от вашей конфигурации. По умолчанию он будет отброшен по умолчанию, как указано выше. См. проверьте настройки переполнения/очереди< /а>. Это самый безопасный вариант с точки зрения памяти и процессора. Вы можете отбросить, заблокировать (остановить основной поток) или увеличить очередь (из-за использования памяти).

будут ли запущены дополнительные потоки [B1 ... Bn]? (это приведет к затоплению пула соединений)

№ 1 Таймер, 1 пул потоков. Подробности см. на странице MSDN для Таймер или справочный источник.

person Julian    schedule 25.11.2016
comment
Не учел флаг throwExceptions. Спасибо что подметил это! Я обновил вопрос, не могли бы вы взглянуть еще раз? - person thedev; 28.11.2016