Как сохранить файл журнала в linux sever при отправке журналов в elk с помощью syslog - PullRequest
0 голосов
/ 06 июня 2019

Я использую докер и стек лося для логов. Я отправил журнал своих микросервисов, используя syslog в моем файле logback.xml. Однако на сервере нет файлов журналов, хотя микросервисы создавали файлы журналов на моем локальном компьютере при работе с Eclipes IDE. Я также использовал файл docker-compose для создания Logstash, Elasticsearch и Kibana. Проблема в том, что когда нам нужно завершить работу докерских контейнеров, предыдущие журналы отсутствуют. Что является большой проблемой.

Вот проблемы

1 Это способ сохранить файл журнала на сервере при отправке журналов в стек elk?

2 Если нет, это способ сохранить журнал с помощью elk-stack навсегда?

Я также добавил свой файл docker-compose для стека elk, файла logstash.config и logback.xml микросервиса.

докер-compose.yml

version: '3'
services:
    elasticsearch:
        image: elasticsearch:6.5.0
        ports:
            - '9200:9200'
            - '9300:9300'
    kibana:
        image: kibana:6.5.0
        ports:
            - '5601:5601'
        depends_on:
            -  elasticsearch
    logstash:
        image: logstash:6.5.0
        ports:
            - '5000:5000'
        volumes:
            - $PWD/elk-config:/elk-config
        command: logstash -f /elk-config/logstash.config
        depends_on:
            -  elasticsearch

logstash.config

input {
    tcp {
    type => syslog
    port => 5000
    }
    udp {
    port => 5000
    type => syslog
    }
}
filter {
    if [type] == "syslog" {
        grok {
             match => { "message" => "%{TIMESTAMP_ISO8601:timestamp}\s+%{LOGLEVEL:severity}\s+\[%{DATA:service},%{DATA:trace},%{DATA:span},%{DATA:exportable}\]\s+%{DATA:pid}\s+---\s+\[%{DATA:thread}\]\s+%{DATA:class}\s+:\s+%{GREEDYDATA:rest}" }
        }  
    }
}
output {
    elasticsearch {
    hosts => "elasticsearch"
    ssl => "false"
    index => "my-logs"
    document_type => "v1"
    }
}

logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="5 seconds">
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
​
    <property scope="context" name="my-service" value="my-service"/>
    <property name="LOG_FILE" value="${BUILD_FOLDER:-logs}/${my-service}"/>​
    <property name="CONSOLE_LOG_PATTERN"
          value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>

<!-- Appender to log to console -->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        <!-- Minimum logging level to be presented in the console logs-->
        <level>DEBUG</level>
    </filter>
    <encoder>
        <pattern>${CONSOLE_LOG_PATTERN}</pattern>
        <charset>utf8</charset>
    </encoder>
</appender>

<!-- Appender to log to file -->​
<appender name="flatfile" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${LOG_FILE}</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.gz</fileNamePattern>
        <maxHistory>10</maxHistory>
    </rollingPolicy>
    <encoder>
        <pattern>${CONSOLE_LOG_PATTERN}</pattern>
        <charset>utf8</charset>
    </encoder>
</appender>
​
<!-- Appender to log to file in a JSON format -->
<appender name="logstash" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${LOG_FILE}.json</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <fileNamePattern>${LOG_FILE}.json.%d{yyyy-MM-dd}.gz</fileNamePattern>
        <maxHistory>10</maxHistory>
    </rollingPolicy>
    <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
        <providers>
            <timestamp>
                <timeZone>UTC</timeZone>
            </timestamp>
            <pattern>
                <pattern>
                    {
                    "severity": "%level",
                    "service": "${springAppName:-}",
                    "trace": "%X{X-B3-TraceId:-}",
                    "span": "%X{X-B3-SpanId:-}",
                    "parent": "%X{X-B3-ParentSpanId:-}",
                    "exportable": "%X{X-Span-Export:-}",
                    "pid": "${PID:-}",
                    "thread": "%thread",
                    "class": "%logger{40}",
                    "rest": "%message"
                    }
                </pattern>
            </pattern>
        </providers>
    </encoder>
</appender>

<appender name="SYSLOG"
    class="ch.qos.logback.classic.net.SyslogAppender">
    <syslogHost>172.26.83.148</syslogHost>
    <port>5000</port>
    <facility>LOCAL1</facility>
    <suffixPattern>[%thread] %logger %msg</suffixPattern>
</appender>
​
<root level="INFO">
    <appender-ref ref="console"/>
    <appender-ref ref="logstash"/>
    <appender-ref ref="flatfile"/>
    <appender-ref ref="SYSLOG"/>
</root>

Что я здесь не так делаю? Любая помощь будет благодарна.

Заранее большое спасибо.

Ответы [ 2 ]

0 голосов
/ 07 июня 2019

Рабочий процесс высокого уровня для регистрации с контейнерами:

application stdout/stderr -> docker logging driver -> remote logging server

Это соответствует дизайну, основанному на 12 факторах приложения . Преимущество этого дизайна в том, что приложение можно перемещать из среды в среду без необходимости перенастраивать. Вместо этого сам докер-хост отвечает за получение журналов на удаленный сервер.

В логингах драйверов есть много опций. По умолчанию используется драйвер регистрации json, который заключает stdout в некоторые метаданные json, чтобы отслеживать детали, например, когда была написана каждая строка, и была ли она stdout или stderr. Вы можете переключить этот драйвер регистрации, чтобы перейти на эластичный через fluentd или gelf. Тем не менее, я не фанат изменения драйвера регистрации по двум причинам. Во-первых, если драйвер журналирования когда-либо зависает, что может произойти, когда у вашего сервера журналирования есть сбой, ваши приложения могут зависнуть, если они заполняют свой буфер stdout, превращая небольшое отключение журналирования в крупное отключение бизнеса. И, во-вторых, без драйвера ведения журнала json docker logs не будет работать, что исключает возможность локальных администраторов помогать в устранении неполадок.

Вместо этого я предпочитаю использовать какой-нибудь сервер пересылки журналов. В Elastic общим пересылщиком является Filebeat (если вы были на Splunk, у них есть свой универсальный пересылщик). Затем вы покидаете журналы докера, используя драйвер ведения журнала json, что позволяет docker logs работать с существующими контейнерами. А Filebeat передает эти журналы контейнеров на центральный сервер Elastic, давая вам постоянство при удалении контейнеров.

Подробнее о запуске Filebeat см. В документации Elastic: https://www.elastic.co/guide/en/beats/filebeat/current/running-on-docker.html

0 голосов
/ 07 июня 2019

Вам нужно изменить

volumes:
  - $PWD/elk-config:/elk-config

до

volumes:
  - $PWD/elk-config:/elk-config
  - $PWD/logs:/logspath/inside/container/

Так что журналы изнутри контейнера также сохраняются на вашем хост-компьютере. Вот так вы увидите файлы на хост-машине

...