近几日闲来无事,工作摸鱼之时在码云上发现一个更加轻量级的分布式日志系统 PlumeLog ,就研究了一下,写了一个 demo,做个记录
一、PlumeLog 简介
无入侵的分布式日志系统,基于 log4j、log4j2、logback 搜集日志,设置链路 ID,方便查询关联日志
基于 elasticsearch 作为查询引擎
高吞吐,查询效率高
全程不占应用程序本地磁盘空间,免维护;对于项目透明,不影响项目本身运行
无需修改老项目,引入直接使用,支持 dubbo,支持 springcloud
二、准备工作
服务端安装
首先是消息队列,PlumeLog 适配了 redis 或 kafka,一般项目 redis 足够了,我这边也是直接用 redis,redis 官网: https://redis.io
然后需要安装 elasticsearch,官网下载地址: https://www.elastic.co/cn/downloads/past-releases
最后下载 Plumelog 的程序包,plumelog-server,下载地址: https://gitee.com/frankchenlong/plumelog/releases
服务启动
三、修改配置
Plumelog 的压缩包解压后有这些文件
修改 application.properties,这边贴上我的配置,主要要改的就是 redis 和 es 的配置
spring.application.name=plumelog_serverserver.port=8891spring.thymeleaf.mode=LEGACYHTML5spring.mvc.view.prefix=classpath:/templates/spring.mvc.view.suffix=.htmlspring.mvc.static-path-pattern=/plumelog/**
#值为4种 redis,kafka,rest,restServer#redis 表示用redis当队列#kafka 表示用kafka当队列#rest 表示从rest接口取日志#restServer 表示作为rest接口服务器启动#ui 表示单独作为ui启动plumelog.model=redis
#如果使用kafka,启用下面配置#plumelog.kafka.kafkaHosts=172.16.247.143:9092,172.16.247.60:9092,172.16.247.64:9092#plumelog.kafka.kafkaGroupName=logConsumer
#redis配置,3.0版本必须配置redis地址,因为需要监控报警plumelog.redis.redisHost=127.0.0.1:6379#如果使用redis有密码,启用下面配置plumelog.redis.redisPassWord=123456plumelog.redis.redisDb=0
#如果使用rest,启用下面配置#plumelog.rest.restUrl=http://127.0.0.1:8891/getlog#plumelog.rest.restUserName=plumelog#plumelog.rest.restPassWord=123456
#elasticsearch相关配置plumelog.es.esHosts=127.0.0.1:9200#ES7.*已经去除了索引type字段,所以如果是es7不用配置这个,7.*以下不配置这个会报错#plumelog.es.indexType=plumelog#索引分片数量设定,建议值:单日日志大小/ES节点机器jvm内存大小 合理的分片大小保证ES写入效率和查询效率plumelog.es.shards=5plumelog.es.replicas=0plumelog.es.refresh.interval=30s#日志索引建立方式day表示按天、hour表示按照小时plumelog.es.indexType.model=day#ES设置密码,启用下面配置#plumelog.es.userName=elastic#plumelog.es.passWord=FLMOaqUGamMNkZ2mkJiY
#单次拉取日志条数plumelog.maxSendSize=5000#拉取时间间隔,kafka不生效plumelog.interval=1000
#plumelog-ui的地址 如果不配置,报警信息里不可以点连接plumelog.ui.url=http://127.0.0.1:8891
#管理密码,手动删除日志的时候需要输入的密码admin.password=123456#日志保留天数,配置0或者不配置默认永久保留admin.log.keepDays=30
#登录配置#login.username=admin#login.password=admin
复制代码
先不启动 plumelog-server,等最后启动
提升性能推荐参考配置方法
单日日志体量在 50G 以内,并使用的 SSD 硬盘
plumelog.es.shards=5
plumelog.es.replicas=0
plumelog.es.refresh.interval=30s
plumelog.es.indexType.model=day
单日日志体量在 50G 以上,并使用的机械硬盘
plumelog.es.shards=5
plumelog.es.replicas=0
plumelog.es.refresh.interval=30s
plumelog.es.indexType.model=hour
单日日志体量在 100G 以上,并使用的机械硬盘
plumelog.es.shards=10
plumelog.es.replicas=0
plumelog.es.refresh.interval=30s
plumelog.es.indexType.model=hour
单日日志体量在 1000G 以上,并使用的 SSD 硬盘,这个配置可以跑到 10T 一天以上都没问题
plumelog.es.shards=10
plumelog.es.replicas=1
plumelog.es.refresh.interval=30s
plumelog.es.indexType.model=hour
plumelog.es.shards 的增加和 hour 模式下需要调整 ES 集群的最大分片数
PUT /_cluster/settings{ "persistent": { "cluster": { "max_shards_per_node":100000 } }}
复制代码
四、创建 springboot 项目
项目配置
pom.xml
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.4.3</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>demo-mybatis</artifactId> <version>0.0.1-SNAPSHOT</version> <name>demo-mybatis</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.4</version> </dependency>
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!--分布式日志收集plumelog--> <dependency> <groupId>com.plumelog</groupId> <artifactId>plumelog-logback</artifactId> <version>3.3</version> </dependency> <dependency> <groupId>com.plumelog</groupId> <artifactId>plumelog-trace</artifactId> <version>3.3</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> <version>2.1.11.RELEASE</version> <scope>provided</scope> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-core</artifactId> <version>5.5.8</version> </dependency> </dependencies>
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build>
</project>
复制代码
resources 下两个配置文件
application.properties
server.port=8888spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=falsespring.datasource.driver-class-name=com.mysql.cj.jdbc.Driverspring.datasource.username=rootspring.datasource.password=123456spring.datasource.hikari.maximum-pool-size=10# mybatis配置mybatis.type-aliases-package=com.example.demomybatis.modelmybatis.configuration.map-underscore-to-camel-case=truemybatis.configuration.default-fetch-size=100mybatis.configuration.default-statement-timeout=30# jackson格式化日期时间spring.jackson.date-format=YYYY-MM-dd HH:mm:ssspring.jackson.time-zone=GMT+8spring.jackson.serialization.write-dates-as-timestamps=false# sql日志打印logging.level.com.example.demomybatis.dao=debug## 输出的日志文件logging.file.path=/log
复制代码
logback-spring.xml
<?xml version="1.0" encoding="UTF-8" ?><configuration> <appender name="consoleApp" class="ch.qos.logback.core.ConsoleAppender"> <layout class="ch.qos.logback.classic.PatternLayout"> <pattern> %date{yyyy-MM-dd HH:mm:ss.SSS} %-5level[%thread]%logger{56}.%method:%L -%msg%n </pattern> </layout> </appender>
<appender name="fileInfoApp" class="ch.qos.logback.core.rolling.RollingFileAppender"> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>ERROR</level> <onMatch>DENY</onMatch> <onMismatch>ACCEPT</onMismatch> </filter> <encoder> <pattern> %date{yyyy-MM-dd HH:mm:ss.SSS} %-5level[%thread]%logger{56}.%method:%L -%msg%n </pattern> </encoder> <!-- 滚动策略 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 路径 --> <fileNamePattern>log/info.%d.log</fileNamePattern> </rollingPolicy> </appender>
<appender name="fileErrorApp" class="ch.qos.logback.core.rolling.RollingFileAppender"> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>ERROR</level> </filter> <encoder> <pattern> %date{yyyy-MM-dd HH:mm:ss.SSS} %-5level[%thread]%logger{56}.%method:%L -%msg%n </pattern> </encoder>
<!-- 设置滚动策略 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 路径 --> <fileNamePattern>log/error.%d.log</fileNamePattern>
<!-- 控制保留的归档文件的最大数量,超出数量就删除旧文件,假设设置每个月滚动, 且<maxHistory> 是1,则只保存最近1个月的文件,删除之前的旧文件 --> <MaxHistory>1</MaxHistory> </rollingPolicy> </appender>
<appender name="plumelog" class="com.plumelog.logback.appender.RedisAppender"> <appName>mybatisDemo</appName> <redisHost>127.0.0.1</redisHost> <redisAuth>123456</redisAuth> <redisPort>6379</redisPort> <runModel>2</runModel> </appender>
<!-- root 一定要放在最后,因有加载顺序的问题 --> <root level="INFO"> <appender-ref ref="consoleApp"/> <appender-ref ref="fileInfoApp"/> <appender-ref ref="fileErrorApp"/> <appender-ref ref="plumelog"/> </root></configuration>
复制代码
logback 配置文件中注意要加上 plumelog 的 appender,然后在 root 中引用 appender,这个是推送日志到 redis 队列中的配置
traceid 设置及链路追踪全局打点配置
traceid 拦截器配置
package com.example.demomybatis.common.interceptor;
import com.plumelog.core.TraceId;import org.springframework.stereotype.Component;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.util.UUID;
/** * Created by wenbo on 2021/2/25. */@Componentpublic class Interceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { //设置TraceID值,不埋此点链路ID就没有 TraceId.logTraceID.set(UUID.randomUUID().toString().replaceAll("-", "")); return true; }
@Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) { }
@Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { }}
复制代码
package com.example.demomybatis.common.interceptor;
import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.InterceptorRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/** * Created by wenbo on 2021/2/25. */@Configurationpublic class InterceptorConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { // 自定义拦截器,添加拦截路径和排除拦截路径 registry.addInterceptor(new Interceptor()).addPathPatterns("/**"); }}
复制代码
链路追踪全局打点配置
package com.example.demomybatis.common.config;
import com.plumelog.trace.aspect.AbstractAspect;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.springframework.stereotype.Component;
/** * Created by wenbo on 2021/2/25. */@Aspect@Componentpublic class AspectConfig extends AbstractAspect { @Around("within(com.example..*))") public Object around(JoinPoint joinPoint) throws Throwable { return aroundExecute(joinPoint); }}
复制代码
这里要把切入点路径换成自己的包路径
@ComponentScan({"com.plumelog","com.example.demomybatis"})
最后放上 demo 链接:https://gitee.com/wen_bo/demo-plumelog
五、启动项目
先将 springboot 启动起来,然后 java -jar plumelog-server-3.2.jar 启动 plumelog
访问 http://127.0.0.1:8891
默认用户名和密码都是 admin
最后展示一下效果图
作者:wenbo
原文链接:https://www.haowenbo.com/articles/2021/02/25/1614235359857.html
欢迎大家扫码来关注公众号博主,获取文章全部资料,此公众号会持续更新技术干货、不定期分享 Java 进阶面试宝典、Java 核心知识、架构书籍电子版
评论