内容简介:公司项目做了集群实现请求分流,由于线上或多或少会出现请求失败或系统异常,为了查看失败请求的日志信息,我们得将所有服务的日志文件都打开来进行问题的定位分析,操作起来非常麻烦。因此,我们开发组决定设计一套日志查看系统来解决上述问题。默认的,应用服务日志信息会保存在本地服务器的目录中,为了方便查看日志我们应该把多台服务器日志统一输出到一个日志文件中。由于项目使用的 Logback 日志框架和 RabbitMQ 消息队列,这两者正好可以进行整合。
一、前言
公司项目做了集群实现请求分流,由于线上或多或少会出现请求失败或系统异常,为了查看失败请求的日志信息,我们得将所有服务的日志文件都打开来进行问题的定位分析,操作起来非常麻烦。因此,我们开发组决定设计一套日志查看系统来解决上述问题。
二、实现思路
默认的,应用服务日志信息会保存在本地服务器的目录中,为了方便查看日志我们应该把多台服务器日志统一输出到一个日志文件中。
由于项目使用的 Logback 日志框架和 RabbitMQ 消息队列,这两者正好可以进行整合。
因此,我们可以将项目代码中的日志输出到 RabbitMQ 队列中,通过 Logstash 读取队列数据,最后再输出到一个日志文件中。
三、准备环境
测试环境:IP 为 192.168.2.13 的 CentOS 7 系统
# 3.1 RabbitMQ 配置
首先需要搭建 RabbitMQ 环境,可以参考本站 《CentOS 7.2 安装 RabbitMQ》 进行搭建。
搭建完成后,登录 RabbitMQ 的管理界面,需要操作如下步骤:
- 创建一个名为 log_queue 的队列
- 创建一个名为 rabbit.log 的交换器(direct 类型)
- 将 log_queue 队列绑定到 rabbit.log 交换机上
操作演示图:
# 3.2 Logstash 配置文件
修改 Logstash 配置文件,本站也有 Logstash 相关的博文,读者可移至《Logstash 基础入门》 查看。
- input {
- rabbitmq {
- type =>"all"
- durable => true
- exchange => "rabbit.log"
- exchange_type => "direct"
- key => "info"
- host => "192.168.2.13"
- port => 5672
- user => "light"
- password => "light"
- queue => "log_queue"
- auto_delete => false
- output {
- file {
- path => "/usr/test-log/test-%{+YYYY-MM-dd}.log"
- codec => multiline {
- pattern => "^\d"
- negate => true
- what => "previous"
注意: multiline 是 Logstash 的插件,需要手动安装。
配置表示 Logstash 服务从 RabbitMQ 读取日志信息,输出到指定的目录文件中。
四、编码
# 4.1 依赖
列出主要依赖:
org.springframework.boot spring-boot-starter-amqp org.springframework.amqp spring-rabbit
# 4.2 日志文件
名为 logback-spring.xml
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n - class="org.springframework.amqp.rabbit.logback.AmqpAppender">
%n ]]> 192.168.2.13:5672 light light true direct rabbit.log info true UTF-8 true NON_PERSISTENT false
配置中的 exchangeType 和 exchangeName 就是我们上边创建的交换机的类型和名称。
# 4.3 测试类
自定义异常:
- public class CustomException extends RuntimeException{
- private static final long serialVersionUID = 1L;
- private int code;
- private String msg;
- public CustomException(int code, String msg) {
- super(msg);
- this.code = code;
- this.msg = msg;
- public int getCode() {
- return code;
- public void setCode(int code) {
- this.code = code;
- public String getMsg() {
- return msg;
- public void setMsg(String msg) {
- this.msg = msg;
模拟打印日志:
- @Component
- public class DemoTask {
- private static Logger logger = LoggerFactory.getLogger(DemoTask.class);
- private int num = 1;
- @Scheduled(fixedRate = 3000)
- public void writeLog() {
- try {
- if (num % 5 == 0) {
- throw new CustomException(500, "自定义异常错误");
- logger.info("==={}===={}","hello rabbitmq", System.currentTimeMillis());
- num++;
- } catch (CustomException e) {
- e.printStackTrace();
- logger.error("=={}==", e);
五、代码测试
执行启动类:
- @EnableScheduling
- @SpringBootApplication
- public class RabbitmqTestApplication {
- public static void main(String[] args) {
- SpringApplication.run(RabbitmqTestApplication.class, args);
执行结果如下图:
代码运行的日志信息已经输出到指定日志文件中了。
补充
由于多台服务器的日志都打印到同一个文件,为了区分日志来源,我们还得需要打印出日志信息对应的主机 ip 地址。具体实现步骤如下:
- 自定义日志转换器
需要继承 ClassicConverter 类
- public class CustomLogConverter extends ClassicConverter {
- public String convert(ILoggingEvent event) {
- try {
- return InetAddress.getLocalHost().getHostAddress();
- } catch (UnknownHostException e) {
- e.printStackTrace();
- return null;
- 修改 logback-spring.xml 文件
以下只张贴关键配置信息
- class="org.springframework.amqp.rabbit.logback.AmqpAppender">
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。