logback整合rabbitmq实现消息记录日志

logback.xml文件配置

   <!-- 配置rabbitmq的信息,数据取值yml -->
 
 <springProperty name="rabbitmqHost" source="spring.rabbitmq.host"/>
 <springProperty name="rabbitmqPort" source="spring.rabbitmq.port"/>
 <springProperty name="rabbitmqUsername" source="spring.rabbitmq.username"/>
 <springProperty name="rabbitmqPassword" source="spring.rabbitmq.password"/>
 <springProperty name="rabbitmqvirtualHost" source="spring.rabbitmq.virtual-host"/>


 <!-- 配置rabbitmq的日志记录appender -->

<appender name="LogAmqpAppender" class="org.springframework.amqp.rabbit.logback.AmqpAppender">
 
        <!--Layout(纯文本)而不是格式化的JSON -->
        <layout>
            <pattern>
           {"source":"%c-%L","createtime":"%d{yyyy-MM-dd HH:mm:ss}","thread":"%thread","level":"%-5level", "logTrackId": "%X{logTrackId}", "requestUri":"%X{requestUri}", "msg":"%msg"}
            </pattern>
        </layout>
        <host>${rabbitmqHost}</host>
        <port>${rabbitmqPort}</port>
        <username>${rabbitmqUsername}</username>
        <password>${rabbitmqPassword}</password>
        <virtualHost>${rabbitmqvirtualHost}</virtualHost>
        <declareExchange>true</declareExchange>
        <exchangeType>direct</exchangeType>
        <exchangeName>log.exchange.direct</exchangeName>
        <routingKeyPattern>logDirectQueue</routingKeyPattern>
        <generateId>true</generateId>
        <charset>UTF-8</charset>
        <durable>false</durable>
        <autoDelete>false</autoDelete>
        <deliveryMode>NON_PERSISTENT</deliveryMode>
    </appender>

    <!-- root 级别的配置 -->

    <root level="INFO">
        <appender-ref ref="LogAmqpAppender" />

    </root>

yml文件配置

  # rabbitmq
  rabbitmq:
    host: 132.33.228.149
    username: admin
    password: admin@2023$
    port: 5673
        #虚拟host 可以不设置,使用server默认host
    virtual-host: /
    connection-timeout: 10000
    listener:
      simple:
        prefetch: 1 # 每次只能获取一条,处理完成才能获取下一条
        acknowledge-mode: manual #一定改为要手动确认模式

代码配置rabbitmq信息

package com.xx.weixin.rabbitmq;


import java.util.HashMap;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;




/**
* @author 作者 srp
* @version 创建时间:2023-12-1 16:42:41
* 
*/
@Configuration

public class RabbitMqLogConfig {
	
	@Autowired
    private RabbitAdmin rabbitAdmin;
    //强制用此方法生成自己希望的队列
	@Bean
    public Queue logDirectQueue() {
	     //设置过期时间,以毫秒为单位
        HashMap<String, Object> map = new HashMap<>();
        map.put("x-message-ttl", 60000);
        //true,false跟logback.xml对应
        Queue queue = new Queue( "logDirectQueue", true,false,false,map);
        rabbitAdmin.declareQueue(queue);
        return queue;

    }
 
    @Bean
    public DirectExchange logDirectExchange() {
        //true,false跟logback.xml对应

        return new DirectExchange("log.exchange.direct", false, false);
    }
 
    /**
     * 根据路由键绑定队列到交换器上
     *
     * @return
     */
    @Bean
    public Binding logDirectBinding() {
        return BindingBuilder.bind(logDirectQueue()).to(logDirectExchange()).with("logDirectQueue");
    }
    
    @Bean
    public RabbitAdmin rabbitAdmin(ConnectionFactory defaultConnectionFactory){
        return new RabbitAdmin(defaultConnectionFactory);
    }

}

测试客户端

package com.xx.pyt.confg;
import java.io.IOException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import org.springframework.amqp.core.Message;

import com.rabbitmq.client.Channel;

///**
//* @author 作者 srp
//* @version 创建时间:2023-12-1 16:45:44
//* 
//*/
@Component

public class DirectConsumer {
	protected final Logger log = LoggerFactory.getLogger(this.getClass());
	@RabbitListener(bindings = @QueueBinding(value = @Queue(value = "logDirectQueue", durable = "false"),
			exchange = @Exchange(name = "log.exchange.direct", durable = "false", type = "direct"),key ="logDirectQueue"))

    @RabbitHandler
    public void handleMessage(String msg, Channel channel, Message message)  throws IOException {
        try {
            // 处理消息逻辑
            processMessage(msg);
            
            // 手动ack确认
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            // 手动nack拒绝,并要求重新投递
            channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
            log.error(e.getMessage(), e);
        }
    }
 
    private void processMessage(String message) {
        // 模拟处理消息过程
        log.info("Processing message: " + message);
        
       
    }


}

此外,如果要对日志进行链路标记,可以是用MDC

package com.xxm.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;

import org.slf4j.MDC;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

import com.ylkh.admin.entity.MyUser;
import com.ylkh.security.dto.JwtUserDto;

import cn.hutool.core.lang.UUID;
import lombok.extern.slf4j.Slf4j;

/**
* @author 作者 srp
* @version 创建时间:2022年1月4日 下午12:52:43
* 
*/
@Slf4j
@Component
@WebFilter(urlPatterns = "/**",filterName = "tlFilter")
public class TraceLogLocalFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
      log.debug("链路过滤器初始化");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    	  HttpServletRequest request = (HttpServletRequest) servletRequest;
   	if(SecurityContextHolder.getContext().getAuthentication()!=null&&!"anonymousUser".equals(SecurityContextHolder.getContext().getAuthentication().getPrincipal())) {
   		     //log.info(""+SecurityContextHolder.getContext().getAuthentication().getPrincipal());
             JwtUserDto jwtUserDto = (JwtUserDto) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
             MyUser myUser = jwtUserDto.getMyUser();
             MDC.put("user", myUser.getUserName());

    	} 
   	  String logtrackId = UUID.randomUUID(true).toString();
   	  if(!request.getRequestURI().contains(".css")&&!request.getRequestURI().contains(".js")&&!request.getRequestURI().contains(".html"))
    	//添加MDC日志
   	    { 
        MDC.put("logTrackId",logtrackId);
        MDC.put("requestUri", request.getRequestURI());
   	     }
        try {
            filterChain.doFilter(servletRequest, servletResponse);
        }finally{
            //移除MDC日志
            MDC.remove(logtrackId);
        }
    //    log.info("过滤器执行完成");
    }

    @Override
    public void destroy() {
        log.warn("过滤器销毁");

    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SLF4J 是一个简单的日志门面,它提供了一组日志 API,可以与许多流行的日志框架(例如 logbacklog4j、java.util.logging)集成。而 logback 则是一个功能强大的日志框架,它是 log4j 框架的继承者,提供了更好的性能和更丰富的特性。 要使用 SLF4J + logback 实现日志输出和记录,需要按照以下步骤进行: 1. 引入依赖:在项目的 pom.xml 文件中加入以下依赖: ``` <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.30</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> </dependency> ``` 2. 配置 logback.xml 文件:在项目的 src/main/resources 目录下创建 logback.xml 文件,并配置日志输出的格式、级别、输出目标等信息。以下是一个简单的 logback.xml 配置示例: ``` <configuration> <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender> <root level="INFO"> <appender-ref ref="console" /> </root> </configuration> ``` 该配置将日志输出到控制台中,并显示日志的时间、线程、级别、类名和消息内容。 3. 在代码中使用 SLF4J API:在需要记录日志的代码中,使用 SLF4J API 进行日志记录。以下是一个示例: ``` import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class MyClass { private static final Logger LOGGER = LoggerFactory.getLogger(MyClass.class); public void doSomething() { LOGGER.info("This is a log message."); } } ``` 在这个示例中,我们使用 LoggerFactory.getLogger() 方法获取了一个 Logger 对象,并使用该对象进行日志记录。在记录日志时,我们使用了 LOGGER.info() 方法,指定日志的级别为 INFO。 以上就是使用 SLF4J + logback 实现日志输出和记录的基本步骤。通过 SLF4J,我们可以方便地切换不同的日志框架,而 logback 则提供了强大的日志功能,例如异步日志记录、定时滚动日志文件等。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值