安装ELK

本文采用docker-compose安装docker-elk,请先安装docker及docker-compose内容

docker compose up setup

docker compose up -d
  • 访问:http://localhost:5601 账号ekastic 密码为.env修密码

    image

调整logstash

配置多端口形式

  • 在docker-elk当前目录编辑docker-compose.yml配置文件

  • 找到logstash的配置,如下:

image

  • 修改为端口段的形式

services:
	logstash:
		port:
			# 增加端口
			- "50000-50010:50000-50010/tcp"
      		- "50000-50010:50000-50010/udp"

增加索引权限

  • 编辑vim setup/roles/logstash_writer.json​

    {
      "cluster": [
        "manage_index_templates",
        "monitor",
        "manage_ilm"
      ],
      "indices": [
        {
          "names": [
            "logs-generic-default",
            "logstash-*",
            "ecs-logstash-*",
            "springboot-*" // 自定义索引前缀
          ],
          "privileges": [
            "write",
            "create",
            "create_index",
            "manage",
            "manage_ilm"
          ]
        },
        {
          "names": [
            "logstash",
            "ecs-logstash"
          ],
          "privileges": [
            "write",
            "manage"
          ]
        }
      ]
    }
    

修改logstash配置


├── logstash
│   ├── config
│   │   └── logstash.yml
│   ├── Dockerfile
│   └── pipeline
│       └── logstash.conf
  • 在 logstash/pipline/logstash.conf 进行配置(如需要接入多个不同的应用日志收集则配置不同的端口进行区分)

    input {
            beats {
                    port => 5044
                    type => 'beats'
            }
    
            tcp {
                    port => 50000
                    type => 'test1'
            }
    
            tcp {
                    port => 50001
                    type => 'test2'
            }
    
    
    }
    
    ## Add your filters / logstash plugins configuration here
    
    output {
    
            if [type] == 'beats' {
                    elasticsearch {
                            hosts => "elasticsearch:9200"
                            user => "logstash_internal"
                            password => "${LOGSTASH_INTERNAL_PASSWORD}"
                    }
    
            } else if [type] == 'test1' {
                    elasticsearch {
                            hosts => "elasticsearch:9200"
                            user => "logstash_internal"
                            password => "${LOGSTASH_INTERNAL_PASSWORD}"
                            index => "springboot-test1%{+YYYY.MM}"
                    }
    
            } else if [type] == 'test2' {
                    elasticsearch {
                            hosts => "elasticsearch:9200"
                            user => "logstash_internal"
                            password => "${LOGSTASH_INTERNAL_PASSWORD}"
                            index => "springboot-test2%{+YYYY.MM}"
                    }
            }
    }
    

以上内容修改完成后重启下elk

docker compose up setup

docker compose down

docker compose up -d

Springboot接入ELK

使用的是log4j2, 在resources下创建对象 log4j2-spring.xml​

其中 host​ 就是主机的ip​,port​是50000​ 具体可以在docker-elk​ 中的 logstash/pipeline/logstash.conf​ 中配置

  • 采用异步的方式

<Appenders>	    
	 <Socket name="Logstash" host="127.0.0.1" port="50000" protocol="TCP">
            <JsonLayout compact="true" eventEol="true">
                <!-- 可读时间 -->
                <KeyValuePair key="timestamp" value="%d{yyyy-MM-dd HH:mm:ss.SSS}"/>
            </JsonLayout>
        </Socket>

        <Async name="LogstashAsync">
            <AppenderRef ref="Logstash"/>
        </Async>
</Appenders>

<loggers>
	<Root level="info">
           <Appender-ref ref="LogstashAsync" /> <!--ELK-->
      </Root>
</loggers>
  • 完整配置参考

<?xml version="1.0" encoding="UTF-8"?>
<!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出-->
<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
<configuration monitorInterval="5">
    <!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->

    <!--变量配置-->
    <Properties>
        <Property name="LOG_EXCEPTION_CONVERSION_WORD">%xwEx</Property>
        <Property name="LOG_LEVEL_PATTERN">%5p</Property>
        <Property name="LOG_DATEFORMAT_PATTERN">yyyy-MM-dd HH:mm:ss.SSS</Property>

        <!-- 定义日志存储的路径 -->
        <Property name="FILE_LOG_BASE_PATH">./system-log</Property>
        <Property name="APPLICATION_NAME">${spring.application.name}</Property>

        <!-- 控制台的日志格式 -->
        <Property name="CONSOLE_LOG_PATTERN">%clr{%d{${sys:LOG_DATEFORMAT_PATTERN}}}{faint} %clr{${sys:LOG_LEVEL_PATTERN}} %clr{%pid}{magenta} %clr{---}{faint} %clr{[%15.15t]}{faint} %clr{%-40.40c{1.}}{cyan} %clr{:}{faint} %m%n${sys:LOG_EXCEPTION_CONVERSION_WORD}</Property>
        <!-- 日志文件的日志格式 -->
        <Property name="FILE_LOG_PATTERN">%d{${sys:LOG_DATEFORMAT_PATTERN}} ${sys:LOG_LEVEL_PATTERN} %pid --- [%t] %-40.40c{1.} : %m%n${sys:LOG_EXCEPTION_CONVERSION_WORD}</Property>
        <!-- 格式化输出:%date表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %msg:日志消息,%n是换行符-->
    </Properties>

    <Appenders>

        <Console name="Console" target="SYSTEM_OUT" follow="true">
            <!--输出日志的格式-->
            <PatternLayout pattern="${sys:CONSOLE_LOG_PATTERN}" charset="${sys:CONSOLE_LOG_CHARSET}"/>
            <!--控制台只输出level及其以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
            <!-- <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/> -->
        </Console>

        <!-- ELK 日志配置-->
        <Socket name="Logstash" host="127.0.0.1" port="50000" protocol="TCP">
            <JsonLayout compact="true" eventEol="true">
                <!-- 可读时间 -->
                <KeyValuePair key="timestamp" value="%d{yyyy-MM-dd HH:mm:ss.SSS}"/>
            </JsonLayout>
        </Socket>

        <Async name="LogstashAsync">
            <AppenderRef ref="Logstash"/>
        </Async>

        <!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
        <RollingFile name="RollingFileInfo" fileName="${FILE_LOG_BASE_PATH}/info.log" filePattern="${FILE_LOG_BASE_PATH}/INFO-%d{yyyy-MM-dd}_%i.log.gz">
            <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
            <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="${FILE_LOG_PATTERN}"/>
            <Policies>
                <!--超过100M增加序号-->
                <SizeBasedTriggeringPolicy size="10MB"/>
                <!-- 每天滚动 -->
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
            </Policies>
            <DefaultRolloverStrategy>
                <!-- 关键点:按时间删除旧文件(优先级高于max序号) -->
                <Delete basePath="${FILE_LOG_BASE_PATH}" maxDepth="1">
                    <IfFileName regex="INFO-\d{4}-\d{2}-\d{2}_\d+\.log\.gz" />       <!-- 匹配压缩日志 -->
                    <IfLastModified age="180d" />             <!-- 180天前的文件 -->
                </Delete>
                <!-- 控制最大序号数(次要限制) -->
                <Max>10</Max>  <!-- 每个日期最多保留10个序号文件 -->
            </DefaultRolloverStrategy>
        </RollingFile>

        <!-- 这个会打印出所有的warn及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
        <RollingFile name="RollingFileWarn" fileName="${FILE_LOG_BASE_PATH}/warn.log" filePattern="${FILE_LOG_BASE_PATH}/WARN-%d{yyyy-MM-dd}_%i.log.gz">
            <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
            <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="${FILE_LOG_PATTERN}"/>
            <Policies>
                <!--超过100M增加序号-->
                <SizeBasedTriggeringPolicy size="10MB"/>
                <!-- 每天滚动 -->
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
            </Policies>
            <DefaultRolloverStrategy>
                <!-- 关键点:按时间删除旧文件(优先级高于max序号) -->
                <Delete basePath="${FILE_LOG_BASE_PATH}" maxDepth="1">
                    <IfFileName regex="WARN-\d{4}-\d{2}-\d{2}_\d+\.log\.gz" />       <!-- 匹配压缩日志 -->
                    <IfLastModified age="180d" />             <!-- 180天前的文件 -->
                </Delete>
                <!-- 控制最大序号数(次要限制) -->
                <Max>10</Max>  <!-- 每个日期最多保留10个序号文件 -->
            </DefaultRolloverStrategy>
        </RollingFile>

        <!-- 这个会打印出所有的error及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
        <RollingFile name="RollingFileError" fileName="${FILE_LOG_BASE_PATH}/error.log" filePattern="${FILE_LOG_BASE_PATH}/ERROR-%d{yyyy-MM-dd}_%i.log.gz">
            <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
            <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="${FILE_LOG_PATTERN}"/>
            <Policies>
                <!--超过100M增加序号-->
                <SizeBasedTriggeringPolicy size="10MB"/>
                <!-- 每天滚动 -->
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
            </Policies>
            <DefaultRolloverStrategy>
                <!-- 关键点:按时间删除旧文件(优先级高于max序号) -->
                <Delete basePath="${FILE_LOG_BASE_PATH}" maxDepth="1">
                    <IfFileName regex="ERROR-\d{4}-\d{2}-\d{2}_\d+\.log\.gz" />       <!-- 匹配压缩日志 -->
                    <IfLastModified age="180d" />             <!-- 180天前的文件 -->
                </Delete>
                <!-- 控制最大序号数(次要限制) -->
                <Max>10</Max>  <!-- 每个日期最多保留10个序号文件 -->
            </DefaultRolloverStrategy>
        </RollingFile>

    </Appenders>

    <!--Logger节点用来单独指定日志的形式,比如要为指定包下的class指定不同的日志级别等。-->
    <!--然后定义loggers,只有定义了logger并引入的appender,appender才会生效-->
    <loggers>

        <!--过滤掉spring和mybatis的一些无用的DEBUG信息-->
        <Logger name="org.mybatis" level="info" additivity="false">
            <AppenderRef ref="Console"/>
        </Logger>
        <!--监控系统信息-->
        <!--若是additivity设为false,则 子Logger 只会在自己的appender里输出,而不会在 父Logger 的appender里输出。-->
        <Logger name="org.springframework" level="info" additivity="false">
            <AppenderRef ref="Console"/>
        </Logger>

        <Root level="info">
            <Appender-ref ref="Console"/>
            <Appender-ref ref="RollingFileInfo"/>
            <Appender-ref ref="RollingFileWarn"/>
            <Appender-ref ref="RollingFileError"/>
            <Appender-ref ref="LogstashAsync"/> <!-- 如不需要其他日志打印,可只保留这个配置即可 -->
        </Root>
    </loggers>

</configuration>

测试并查看ELK日志

本地启动springboot项目,ELK会收集日志,可在平台上查看

新建日志视图

  • 进入elastic平台

    image

  • 创建view

    image

  • 查看是否有对应索引信息

    image

  • 配置view信息

    比如我需要查看api的所有日志,现在因为是按月分的索引索引我们可以把对应的全加上,用通配符

    image

  • 保持测试日志是否正常打印输出

    image

好了,以上就是基础的elk的安装和使用了,赶紧试试吧。