在使用log4j將日誌寫到kafka時碰到一個問題,就是KafkaLog4jAppender出現異常後的日誌處理
直接使用log會將日誌寫到kafka,最終死循環,因此以上的類中若是出現異常,能夠將日誌寫到本地文件中
能夠使用兩種方式:java
本文記錄第二種方式,主要功能點爲使用代碼方式配置Log4j 的logger
具體代碼以下:apache
注意,相關的類都是log4j的,不是slf4j的
public class KafkaLog4jAppender extends AppenderSkeleton { private static final Logger log = Logger.getLogger(KafkaLog4jAppender.class.getName()); // private static final Logger log = LoggerFactory.getLogger(KafkaLog4jAppender.class.getName()); }
@Override public void activateOptions() { //log4j單獨配置,將當前類中錯誤信息輸出到文件中 log.removeAllAppenders();//移除全部的appender log.setLevel(Level.WARN);//設置日誌級別 log.setAdditivity(false);//移除繼承關係 // 生成新的Appender DailyRollingFileAppender appender = new DailyRollingFileAppender(); PatternLayout layout = new PatternLayout(); String conversionPattern = "%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L ---- %m%n"; layout.setConversionPattern(conversionPattern); appender.setLayout(layout); // log輸出路徑 appender.setFile("d://temp//kafka.error"); appender.setDatePattern("'.'yyyy-MM-dd'.log'"); appender.setEncoding("UTF-8"); // 適用當前配置 appender.activateOptions(); // 將新的Appender加到Logger中 log.addAppender(appender); }
在下面就能夠直接使用了app
producer.send(record, new Callback() { @Override public void onCompletion(RecordMetadata metadata, Exception exception) { if (!Objects.isNull(exception)) { log.warn("kafka異步日誌發送失敗,消息內容:" + message); exception.printStackTrace(); } } });
效果如圖異步
另附一個Log4j的配置文件ide
# LOG4J配置 log4j.rootCategory=info,stdout,kafka # 控制檯輸出 log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n #error級別的日誌輸出到單獨的文件 #log4j.logger.error=errorfile # error日誌輸出 log4j.appender.errorfile=org.apache.log4j.DailyRollingFileAppender log4j.appender.errorfile.file=d:/temp/test.error.log log4j.appender.errorfile.DatePattern='.'yyyy-MM-dd log4j.appender.errorfile.Threshold=ERROR log4j.appender.errorfile.layout=org.apache.log4j.PatternLayout log4j.appender.errorfile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n ## appender kafka log4j.appender.kafka=com.xiang.demo.log4j.log4jdemo.config.KafkaLog4jAppender log4j.appender.kafka.topic=kafka_log #log4j.appender.kafka.acks=0 log4j.appender.kafka.brokerList=192.168.21.215:9092 #log4j.appender.kafka.compressionType=none #是否同步 #log4j.appender.kafka.syncSend=false log4j.appender.kafka.layout=org.apache.log4j.PatternLayout log4j.appender.kafka.layout.ConversionPattern=%d [%-5p] [%t] - [%l] %m%n ## appender rabbitmq #log4j.appender.rabbitmq=com.xiang.demo.log4j.log4jdemo.config.RabbitmqLog4jAppender #log4j.appender.rabbitmq.host= #log4j.appender.rabbitmq.username= #log4j.appender.rabbitmq.password= #log4j.appender.rabbitmq.virtualhost=/log #log4j.appender.rabbitmq.qububname=log4j_log_rabbitmq #log4j.appender.rabbitmq.layout=org.apache.log4j.PatternLayout #log4j.appender.rabbitmq.layout.ConversionPattern=%d [%-5p] [%t] - [%l] %m%n ## kafka包下的日誌配置 異常只輸出到本地,不輸入到kafka #取消kafka的日誌繼承關係 log4j.additivity.org.apache.kafka=false log4j.logger.org.apache.kafka=warn,stdout,kfkerrfile log4j.additivity.com.xiang.demo.log4j.log4jdemo.config.KafkaLog4jAppender=false log4j.logger.com.xiang.demo.log4j.log4jdemo.config.KafkaLog4jAppender=warn,kfkapderrfile log4j.appender.kfkapderrfile=org.apache.log4j.DailyRollingFileAppender log4j.appender.kfkapderrfile.file=d:/temp/kafka.appender.error log4j.appender.kfkapderrfile.DatePattern='.'yyyy-MM-dd'.log' log4j.appender.kfkapderrfile.layout=org.apache.log4j.PatternLayout log4j.appender.kfkapderrfile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L ---- %m%n log4j.appender.kfkerrfile=org.apache.log4j.DailyRollingFileAppender log4j.appender.kfkerrfile.file=d:/temp/kafka.error log4j.appender.kfkerrfile.DatePattern='.'yyyy-MM-dd'.log' log4j.appender.kfkerrfile.layout=org.apache.log4j.PatternLayout log4j.appender.kfkerrfile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L ---- %m%n