SpringBoot集成MongoDB用于进行日志管理
并不是什么高深的技术,主要是配置,配完了万事好说。
至于MongoDB的使用这里就不多说了。看看我什么时候心血来潮想整理一下再整理一份文章出来。
最基本的pom.xml配置和yml配置。无需多说
<!--MongoDB--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> <!--logback日志框架--> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> </dependency>
#数据库连接属性配置
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/hospital?serverTimezone=Asia/Shanghai
username: root
password: 614
#security配置
jackson:
serialization:
indent_output: true
#Redis配置
redis:
host: 127.0.0.1
port: 6379
#Redis连接池配置
jedis:
pool:
min-idle: 0
max-idle: 8
max-active: 8
max-wait: -1ms
#MongoDB配置
data:
mongodb:
uri: mongodb://127.0.0.1:27017/logs
#mybatis实体类名
mybatis:
type-aliases-package: top.yibobo.hospital.domain
configuration:
#到下划线的表字段自动映射成驼峰命名法
map-underscore-to-camel-case: true
mapper-locations: classpath:mybatis/mapper/*.xml
#设置服务器端口号/session保存时长
server:
port: 8086
#定义日志文件路径
logging:
#file: logs/all.log
level:
org.springframework.security: info
top.yibobo.hospital.mapper: debug
top.yibobo.hospital.util: debug
#JWT配置
jwt:
header: Authorization #请求头部属性名
secret: mySecret #自定义口令
expiration: 604800 #token失效时间
route: #访问路径
authentication:
path: /auth
refresh: /refresh
由于要使用到logback,所以还需要一个logback.xml配置文件,此文件存放于resources目录下
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xml>
<!--logback使用的日志输出文件-->
<configuration scan="true" scanPeriod="3600 seconds" debug="false">
<property name="logDir" value="logs"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<charset>UTF-8</charset>
<pattern>%d [%thread] %-5level %logger{68} %line - logId[[%X{client}][%X{request_id}]] - %msg%n</pattern>
</encoder>
</appender>
<appender name="RollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>TRACE</level>
</filter>
<!-- 可让每天产生一个日志文件,最多 10 个,自动回滚 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${logDir}/file-%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>10</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<appender name="MONGODB" class="top.yibobo.hospital.logback.MongoDBAppender"/>
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="RollingFile"/>
<appender-ref ref="MONGODB"/>
</root>
</configuration>
至此,配置文件书写完毕。轮到重要的具体实现了。
首先定义一个接口,继承MongoRepository
package top.yibobo.hospital.logback;
import org.springframework.data.mongodb.repository.MongoRepository;
public interface LogRepository extends MongoRepository<MyLog,String> {
}
这是日志信息的实体类,可以自己定义
package top.yibobo.hospital.logback;
import java.io.Serializable;
import java.util.Date;
public class MyLog implements Serializable{
private String id;
private String level;
private String message;
private String thread;
private Date ts;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getLevel() {
return level;
}
public void setLevel(String level) {
this.level = level;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getThread() {
return thread;
}
public void setThread(String thread) {
this.thread = thread;
}
public Date getTs() {
return ts;
}
public void setTs(Date ts) {
this.ts = ts;
}
}
这是将日志信息输出到MongoDB的实现类
package top.yibobo.hospital.logback;
import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.core.UnsynchronizedAppenderBase;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import java.util.Date;
/*
将日志信息输出到mongdb的实现类
*/
@Component
public class MongoDBAppender extends UnsynchronizedAppenderBase<LoggingEvent>
implements ApplicationContextAware{
private static LogRepository logRepository;
@Override
protected void append(LoggingEvent loggingEvent) {
MyLog myLog = new MyLog();
myLog.setLevel(loggingEvent.getLevel().toString());
myLog.setMessage(loggingEvent.getFormattedMessage());
myLog.setThread(loggingEvent.getThreadName());
myLog.setTs(new Date());
logRepository.save(myLog);
}
@Override
public void start() {
super.start();
}
@Override
public void stop() {
super.stop();
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if (applicationContext.getAutowireCapableBeanFactory()
.getBean(LogRepository.class)!=null){
logRepository = applicationContext
.getAutowireCapableBeanFactory().getBean(LogRepository.class);
}
}
}
这是日志切面
package top.yibobo.hospital.logback;
import com.mongodb.BasicDBObject;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
@Aspect
@Component
@Order(3)//Order用来定义切面执行顺序
public class WebLogAspect {
//定义日志记录器
private Logger logger = LoggerFactory.getLogger("MONGODB");
@Pointcut("execution(public * top.yibobo.hospital.controller.*.*(..))")
public void weblog(){}
@Before("weblog()")
public void dobefore(JoinPoint joinPoint){
//由于切面类不能从方法入参注入、所以只能这样获取servlet请求对象
ServletRequestAttributes attributes = (ServletRequestAttributes)
RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
//mongodb保存的基本对象(文档)
BasicDBObject object = getBasicDBObject(request,joinPoint);
logger.info(object.toString());
}
private BasicDBObject getBasicDBObject(HttpServletRequest request,JoinPoint joinPoint){
BasicDBObject b = new BasicDBObject();
b.append("RequestURL:",request.getRequestURI().toString());
b.append("METHOD",request.getMethod());
b.append("RemoteAddr",request.getRemoteAddr());
b.append("HEADER",getHeader(request));
//b.append("CLASS_METHOD",joinPoint.getSignature().getDeclaringTypeName()+"."+joinPoint.getSignat);
b.append("Args",Arrays.toString(joinPoint.getArgs()));
return b;
}
private Map<String,String> getHeader(HttpServletRequest request){
Map<String,String> map = new HashMap<>();
Enumeration<String> header = request.getHeaderNames();
while (header.hasMoreElements()){
String key = header.nextElement();
map.put(key,request.getHeader(key));
}
return map;
}
}
