如何使用syslog将日志发送到Elk时在Linux服务器中保存日志文件

时间:2019-06-06 04:34:41

标签: docker logging docker-compose microservices elastic-stack

我将docker和elk stack用于日志。我在logback.xml文件中使用syslog发送了微服务的日志。但是,即使当我使用Eclipes IDE运行微服务在本地计算机中创建日志文件时,服务器中也没有日志文件。我还使用了docker-compose文件来设置Logstash,Elasticsearch和Kibana。问题是当我们需要关闭Docker容器时,没有以前的日志。这是个大问题。

这是问题

1他们是在将日志发送到麋鹿堆栈时将日志文件保存在服务器中的一种方法吗?

2如果不是,他们是否可以通过elk-stack永久保存日志?

我还添加了用于麋鹿堆栈的docker-compose文件,logstash.config文件和微服务的logback.xml。

docker-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 :(得分:0)

您需要更改

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

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

这样,来自容器内部的日志实际上也会保存到您的主机中。那就是您在主机上查看文件的方式

答案 1 :(得分:0)

使用容器记录的高级工作流程是:

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

这遵循12 factor app principles开始的设计。这种设计的优点是可以将应用程序从一个环境移到另一个环境,而无需重新配置。相反,泊坞窗主机本身负责将日志获取到远程服务器。

日志记录驱动程序有许多选项。默认值为json日志记录驱动程序,该驱动程序将stdout包装在一些json元数据中,以跟踪详细信息,例如每行的写入时间,是stdout还是stderr。您可以将此日志记录驱动程序切换为通过流利或Gelf进入弹性模式。但是,由于两个原因,我不喜欢更改日志记录驱动程序。首先,如果日志记录驱动程序曾经挂起(这种情况可能在日志服务器中断时发生),则如果应用程序填充了标准缓冲缓冲区,则它们可能会挂起,从而将小型日志中断变成大型业务中断。其次,如果没有json日志记录驱动程序,docker logs将无法工作,从而消除了本地管理员协助调试问题的能力。

相反,我更喜欢使用某种日志转发器。使用Elastic,通用转发器是Filebeat(如果您使用的是Splunk,则它们拥有自己的通用转发器)。然后,您使用json日志记录驱动程序保留docker日志,从而允许docker logs在现有容器上工作。 Filebeat将这些容器日志中继到中央Elastic服务器,从而在删除容器时为您提供持久性。

有关运行Filebeat的更多详细信息,请参见Elastic文档:https://www.elastic.co/guide/en/beats/filebeat/current/running-on-docker.html