【问题标题】:Spring Boot + logback + autowireSpring Boot + logback + autowire
【发布时间】:2016-02-17 19:55:51
【问题描述】:

我正在运行一个使用 logback 的 Spring Boot 应用程序。这个想法是将日志消息发送到 RabbitMQ 服务器。为此,我创建了一个扩展 ch.qos.logback.core.AppenderBase 的附加程序。

这是我的 logback-spring.xml 文件:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="messaging" class="com.foo.logging.appender.MessagingAppenderLogback" />
    <root level="info">
        <appender-ref ref="messaging" />
    </root>
</configuration>

一切都好。但是,在 MessagingAppenderLogback 中,我希望用来发送消息的 RabbitTemplate 为空。

@Component
public class MessagingAppenderLogback extends AppenderBase<ILoggingEvent> {
    @Autowired
    RabbitTemplate rabbitTemplate;

    public MessagingAppenderLogback(){ }

    @Override
    protected void append(ILoggingEvent event) {
        System.out.println("  MessagingAppenderLogback#append w/ event " + event);
        // rabbitTemplate.convertAndSend(event);
    }   
}

根据documentation,我知道“日志系统已在应用程序的早期初始化......”

我想知道我必须做什么才能在我的 appender 中使用 rabbitTemplate。

【问题讨论】:

  • @gonqin 您将看不到自动装配的组件,因为 Spring 正在创建一个实例,而 Logback 也在使用您正在使用的空构造函数创建另一个实例。我也遇到了同样的问题,但是如果您摆脱空构造函数并使用构造函数注入将 EventPublisher 组件添加到控制器,那么一切都应该正常工作。抱歉,我不得不将此作为答案发布,因为我还没有评论的声誉。

标签: spring spring-boot logback


【解决方案1】:

您的 appender 不是 Spring bean,它是由 logback 框架实例化的。您不能使用 Spring 的依赖注入(@Component@Autowired 未处理)。您需要显式实例化 RabbitTemplate。

无论如何,您可能正在寻找这个: http://docs.spring.io/spring-amqp/docs/current/api/org/springframework/amqp/rabbit/logback/AmqpAppender.html

【讨论】:

  • 非常感谢。我花了最后一天尝试通过您的链接使用“完全配置的 AmqpAppender”。我可以看到我的日志消息已发送到 rabbitmq 服务器,但无法弄清楚如何绑定队列以在 xml 文件中进行交换。唯一想到的是在“配置”文件/类中以编程方式这样做。
  • 绑定不是 logback 的业务,你不能在那里声明它们。理想情况下,使用日志的应用程序应该声明绑定。
【解决方案2】:

我用它玩了一会儿,然后让它工作了:

@Component
public class BeanAppender extends AppenderBase<ILoggingEvent> {

    @Autowired
    private UserService userService;

    @Override
    protected void append(ILoggingEvent eventObject) {
        System.out.println("message " + eventObject.getMessage() + " " + eventObject.getLoggerName() + " bean reference" + userService);
    }

    @PostConstruct
    public void init() {
        LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
        context.getLoggerList().forEach(new Consumer<Logger>() {

            @Override
            public void accept(Logger logger) {
                logger.addAppender(BeanAppender.this);
            }
        });

        setContext(context);
        start();
    }
}

假设您不介意以编程方式配置附加程序,它可以为您解决问题。那你就不需要再去碰logback.xml了。

【讨论】:

  • 非常感谢。但是,我看不到您的示例如何能够发送(amqp)消息。我会自己尝试并添加 RabbitTemplate。
  • 我的意思是证明 Spring bean 可以自动装配到 appender,但缺点是您需要以编程方式添加 appender。你现在需要做的就是用你需要的任何东西替换“userService”,所以 RabbitTemplate:)
【解决方案3】:

我遇到了完全相同的问题。但是,在应用您的代码后,我的 Autowired 字段仍然为空 :-(?我应该检查什么?

这是我的代码:

import java.util.Date;
import java.util.function.Consumer;

import javax.annotation.PostConstruct;

import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.stereotype.Component;

import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;

@Component
@EnableAutoConfiguration
public class RabbitMQAppender extends AppenderBase<ILoggingEvent>
{
    @Autowired
    private EventPublisher eventPublisher;

    public RabbitMQAppender()
    {
    }

    @Override
    protected void append(ILoggingEvent logEvent)
    {
        System.out.println("RabbitMQ logger in appender: " + event.toString());
    }

    @PostConstruct
    public void init() {
        LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
        context.getLoggerList().forEach(new Consumer<Logger>() {

            @Override
            public void accept(Logger logger) {
                logger.addAppender(RabbitMQAppender.this);
            }
        });

        setContext(context);
        start();
    }    
}

当您说“不要触摸 logback.xml”时,您的意思是根本没有它还是保持原样?当我保留它时,自动装配字段为空。没有它时,我的appender根本没有使用。

【讨论】:

    猜你喜欢
    • 2023-04-04
    • 2019-01-19
    • 1970-01-01
    • 2020-07-18
    • 2016-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-01
    相关资源
    最近更新 更多