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; } }