多个springboot项目 logstash推送日志到ES

多个springboot项目 logstash推送日志到ES

前面我在https://blog.csdn.net/yyj12138/article/details/124499741中有讲到如何来搭建ELK,这次来谈谈如何将springboot项目的日志推到ES管理。

我们知道一般来说稍微大一点的项目都不会只部署一台机器,那么分布式情况下对日志的管理就比较麻烦,没办法每次排查问题都去各服务器筛选一遍,那样太麻烦了。

logstash为我们提供了file(文件监控)、redis(从redis接收)、mq(从mq接收)、tcp/http(接收tcp或http协议的数据)、beats等等

其中文件监控和tcp/http接收不建议使用,性能不是很好,这里我介绍一下从rabbitMq接收日志。

1、springboot工程的配置

1)引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

2)logback-spring.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
    <define name="ip" class="com.example.boot.config.IpPropertyDefiner"/>
    <springProperty scope="context" name="env" source="spring.profiles.active"/>
    <springProperty scope="context" name="appName" source="spring.application.name"/>
    
    <property name="key" value="^@$^"/>
    <property name="log.level" value="info"/>
    <property name="logstash.pattern" value="${appName}${key}${env}${key}${ip}${key}%d{ISO8601}${key}%t${key}%p${key}%c${key}%m"/>
    <!-- logstash -->
    <appender name="AMQP" class="org.springframework.amqp.rabbit.logback.AmqpAppender">
        <layout>
            <pattern>${logstash.pattern}</pattern>
        </layout>
        <host>ip</host>
        <port>port</port>
        <username>admin</username>
        <password>admin</password>
        <applicationId>dev-boot</applicationId>
        <routingKeyPattern>logstash-rkp</routingKeyPattern>
        <declareExchange>true</declareExchange>
        <exchangeType>direct</exchangeType>
        <exchangeName>logstash-exchange</exchangeName>
        <generateId>true</generateId>
        <charset>UTF-8</charset>
        <durable>true</durable>
        <deliveryMode>PERSISTENT</deliveryMode>
    </appender>
    
    <appender name="ASYNC_ES_INFO" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 不丢失日志,默认如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
        <queueSize>512</queueSize>
        <!-- 添加附加的appender,最多只能添加一个 -->
        <appender-ref ref="AMQP"/>
    </appender>
    
    <springProfile name="test">
        <root level="${log.level}">
            <appender-ref ref="ASYNC_ES_INFO"/>
        </root>
    </springProfile>
</configuration>

这里为了获取当前服务器的ip编写了一个类IpPropertyDefiner,为了在分布式环境下能定位到日志来自哪台机器

@Slf4j
public class IpPropertyDefiner extends PropertyDefinerBase {
    @Override
    public String getPropertyValue() {
        InetAddress ia;
        try {
            ia = InetAddress.getLocalHost();
            return ia.getHostAddress();
        } catch (UnknownHostException e) {
            log.error("日志属性ip获取出错");
        }
        return "";
    }
}

想必你有注意到pattern的格式了吧,为什么是这种格式,后面会讲到

你也可以加上输出到文件的日志配置,做一个备份,关于输出到文件这里我就不具体描述了

2、logstash的配置
input {
    rabbitmq {
        host => "ip"
        port => port
        user => admin
        password => admin
        durable => true
        queue => "logstash-queue"
        codec => plain
        type => appLog
    }
} 

# 过滤、格式化数据
filter {
    mutate{
    # 日志格式使用特殊字符隔开,便于格式化
    # 这里格式化为数组
    split => ["message","^@$^"]
        add_field =>   {
            "appName" => "%{[message][0]}"
        }
        add_field =>   {
            "env" => "%{[message][1]}"
        }
        add_field =>   {
            "ip" => "%{[message][2]}"
        }
        add_field =>   {
            "logTime" => "%{[message][3]}"
        }
        add_field =>   {
            "thread" => "%{[message][4]}"
        }
        add_field =>   {
            "level" => "%{[message][5]}"
        }
        add_field =>   {
            "class" => "%{[message][6]}"
        }
        add_field =>   {
            "msg" => "%{[message][7]}"
        }
    }
    
    # 你还可以使用下面的日期格式化将日志的时间覆盖es的@timestamp
    #date {
    #    match => ["logTime", "ISO8601"]
    #    target => "@timestamp"
    #}
    
    # 移除你不想推给es的字段
    mutate  {
        remove_field => ["@version", "message"]
    }
}   

# es推送配置
output {
	# 判断如果是不规范的数据,同一推送到other索引下
    if [type] == "appLog" and [appName] != "" and [env] != ""{
        elasticsearch {
            hosts => "10.1.59.128:9200"
            index => "%{env}_%{appName}_log_%{+YYYY.MM.dd}"
        }
    } else {
        elasticsearch {
            hosts => "10.1.59.128:9200"
            index => "other_log_%{+YYYY.MM.dd}"
        }
    }
}

filter对日志使用mutate进行格式化,使用特殊字符分割并set到对应的字段中,特殊字符对应logback中的配置,output中的判断[type] == “appLog” and [appName] != “” and [env] != “”,type对应input中的type,防止从其他地方输入的内容污染日志,后面两个主要是区分项目和环境,此时配置已经支持多项目多环境建立不同的索引了。

对日志内容的格式化有很多种方式,比如还可以使用ruby脚本或者gork匹配,logback的日志输出格式还可以配置成json格式,但是我测试发现日志有特殊字符时,会打乱json格式,导致logstash处理json出错。

如果你也想使用ruby脚本,可参考:

ruby {
        code => "
            message = event.get('message')
            jsonMsg = JSON.parse(message)
            event.set('appName', jsonMsg['appName'])
            event.set('ip', jsonMsg['ip'])
            event.set('thread', jsonMsg['thread'])
            event.set('level', jsonMsg['level'])
            event.set('logger', jsonMsg['logger'])
            event.set('trace', jsonMsg['trace'])
            event.set('msg', jsonMsg['msg'])
            event.set('timeTmp', jsonMsg['logTime'])
        "
    }
3、启动与检查

此时启动logstash和springboot项目,会发现mq队列和交换机已经创建好了,有可能交换机和队列没有关联,只需要手动关联一次即可。关联完成以后可以请求一次然后去kibana可视化查看日志。如何查看和创建索引参考https://blog.csdn.net/yyj12138/article/details/124499741

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot是一个简化了应用程序开发的框架,提供了快速构建和运行独立的、生产级的Spring应用程序的能力。Logback是一种日志记录框架,它是由Ceki Gülcü创建的,是Log4j的继任者。Logback支持异步日志记录和策略,具有高性能和低延迟的特点。 而Logstash是一个高度可扩展的开源日志收集和处理工具,它可以从各种数据源收集日志,并将其存储到中央存储库中。使用Logstash,我们可以将Spring Boot应用程序的日志输出发送到集中式日志服务器进行集中管理和处理。 在Spring Boot中,我们可以集成Logback和Logstash来处理应用程序的日志。我们可以通过在项目的依赖管理文件中引入相应的依赖,例如: ```xml <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> </dependency> <dependency> <groupId>net.logstash.logback</groupId> <artifactId>logstash-logback-encoder</artifactId> </dependency> ``` 然后,我们可以通过配置Logback来指定日志的输出格式和目标。我们可以使用Logstash提供的编码器来将日志信息格式化为JSON格式,并将其发送到Logstash服务器。配置示例如下: ```xml <configuration> <appender name="logstash" class="ch.qos.logback.core.ConsoleAppender"> <encoder class="net.logstash.logback.encoder.LogstashEncoder" /> </appender> <root level="info"> <appender-ref ref="logstash" /> </root> </configuration> ``` 通过以上配置,我们可以将Spring Boot应用程序的日志输出到控制台,并通过Logstash日志发送到集中式日志服务器进行集中处理和存储。这样可以方便我们对日志进行监控、检索和分析,有助于排查和解决应用程序中的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值