使用logback实现http请求日志导入mongodb
spring boot自带logback作为其日志新系统,但是在实际工作中,常常需要对日志进行管理或分析,
如果只是单纯的将日志导入文本文件,则在查询时操作过于繁琐,
如果将其导入mysql等关系型数据库进行存储,又太影响系统性能,同时由于Mysql其结构化的信息存储结构,导致在存储时不够灵活。
因此,在此考虑将springboot系统中产出的日志(logback) 存入mongodb中
1.pom.xml 引入依赖
注意排除掉log4j的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
<version>1.5..RELEASE</version>
</dependency> <!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-core -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.</version>
</dependency> <!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.</version>
</dependency>
<!-- log4j 记录日志-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
<version>1.3.8.RELEASE</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency> <!--AOP-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>1.5.7.RELEASE</version>
</dependency>

2.创建实体类: logback.MyLog.java
package com.wutongshu.springboot.logback; import java.io.Serializable;
import java.util.Date; public class MyLog implements Serializable {
private String id;
private String msg;
private Date time;
private String threadName;
private String level; public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} public String getMsg() {
return msg;
} public void setMsg(String msg) {
this.msg = msg;
} public Date getTime() {
return time;
} public void setTime(Date time) {
this.time = time;
} public String getThreadName() {
return threadName;
} public void setThreadName(String threadName) {
this.threadName = threadName;
} public String getLevel() {
return level;
} public void setLevel(String level) {
this.level = level;
}
}
3.添加数据访问接口: LogRepository.java
package com.wutongshu.springboot.logback;
import org.springframework.data.mongodb.repository.MongoRepository;
public interface LogRepository extends MongoRepository<MyLog,String> {
}
4.Appender 类: MongoDBAppender.java
package com.wutongshu.springboot.logback; import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.core.UnsynchronizedAppenderBase;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component; import java.util.Date;
@Component
public class MongoDBAppender extends UnsynchronizedAppenderBase<LoggingEvent> implements
ApplicationContextAware {
private static LogRepository logRepository; @Override
public void start() {
super.start();
}
@Override
public void stop() {
super.stop();
}
@Override
protected void append(LoggingEvent e) {
MyLog myLog = new MyLog();
myLog.setLevel(e.getLevel().toString());
myLog.setMsg(e.getFormattedMessage());
myLog.setThreadName(e.getThreadName());
myLog.setTime(new Date(e.getTimeStamp()));
logRepository.save(myLog);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
if (applicationContext.getAutowireCapableBeanFactory().getBean(LogRepository.class) != null) {
logRepository = (LogRepository) applicationContext.getAutowireCapableBeanFactory().getBean(LogRepository.class);
}
}
}
5.创建切面类记录日志信息
logger取名为MONGODB
通过getBasicDBObject函数从HttpServletRequest和JoinPoint对象中获取请求信息,并组装成BasicDBObject
getHeadersInfo函数从HttpServletRequest中获取header信息
通过logger.info(),输出BasicDBObject对象的信息到mongodb
package com.wutongshu.springboot.logback; import com.mongodb.BasicDBObject;
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
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()
public class WebLogAspect {
private Logger logger=Logger.getLogger("MONGODB"); private ThreadLocal<Long> startTime=new ThreadLocal<>(); @Pointcut("execution(public * com.*.*.web.*.*(..))")
public void webLog(){ } @Before(value = "webLog()")
public void doBefore(JoinPoint point){
startTime.set(System.currentTimeMillis()); logger.info("WebLogAspect.doBefore............");
ServletRequestAttributes attributes=
(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request=attributes.getRequest();
// 获取要记录的日志内容
BasicDBObject logInfo = getBasicDBObject(request, point);
logger.info(logInfo);
} private BasicDBObject getBasicDBObject(HttpServletRequest request, JoinPoint point) {
// 基本信息
BasicDBObject r = new BasicDBObject();
r.append("requestURL", request.getRequestURL().toString());
r.append("requestURI", request.getRequestURI());
r.append("queryString", request.getQueryString());
r.append("remoteAddr", request.getRemoteAddr());
r.append("remoteHost", request.getRemoteHost());
r.append("remotePort", request.getRemotePort());
r.append("localAddr", request.getLocalAddr());
r.append("localName", request.getLocalName());
r.append("method", request.getMethod());
r.append("headers", getHeadersInfo(request));
r.append("parameters", request.getParameterMap());
r.append("classMethod", point.getSignature().getDeclaringTypeName() + "." + point.getSignature().getName());
r.append("args", Arrays.toString(point.getArgs()));
return r;
} /**
* 获取头信息
*
* @param request
* @return
*/
private Map<String, String> getHeadersInfo(HttpServletRequest request) {
Map<String, String> map = new HashMap<>();
Enumeration headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String key = (String) headerNames.nextElement();
String value = request.getHeader(key);
map.put(key, value);
}
return map;
} }
6.创建logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xml> <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-</charset>
<pattern>%d [%thread] %-5level %logger{} %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> <!-- 可让每天产生一个日志文件,最多 个,自动回滚 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${logDir}/file-%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory></maxHistory>
</rollingPolicy> <encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
<charset>UTF-</charset>
</encoder>
</appender>
<!--appender类的路径-->
<appender name="MONGODB" class="com.wutongshu.springboot.logback.MongoDBAppender"/> <root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="RollingFile"/>
<appender-ref ref="MONGODB"/>
</root>
</configuration>
7.在application.properties里添加mongodb的uri

启动MongoDB数据库,可看到多了一个名为logs的database

在java的项目结构上也多了个logs的文件夹

使用logback实现http请求日志导入mongodb的更多相关文章
- Spring Boot中使用log4j实现http请求日志入mongodb
之前在<使用AOP统一处理Web请求日志>一文中介绍了如何使用AOP统一记录web请求日志.基本思路是通过aop去切web层的controller实现,获取每个http的内容并通过log4 ...
- slf4j+logback搭建超实用的日志管理模块
文章转自http://www.2cto.com/kf/201702/536097.html slf4j+logback搭建超实用的日志管理模块(对日志有编号管理):日志功能在服务器端再常见不过了,我们 ...
- 46. Spring Boot中使用AOP统一处理Web请求日志
在之前一系列的文章中都是提供了全部的代码,在之后的文章中就提供核心的代码进行讲解.有什么问题大家可以给我留言或者加我QQ,进行咨询. AOP为Aspect Oriented Programming的缩 ...
- springboot aop + logback + 统一异常处理 打印日志
1.src/resources路径下新建logback.xml 控制台彩色日志打印 info日志和异常日志分不同文件存储 每天自动生成日志 结合myibatis方便日志打印(debug模式) < ...
- MySQL导入MongoDB
一.MongoDB的导入导出 mongoDB的导入导出,分为mongoDB官方提供的工具类,和第三方的工具类.下面依次介绍下: 1.1.mongoDB提供的工具 1.1.1.mongoimport工具 ...
- Logback+ELK+SpringMVC搭建日志收集服务器
(转) 1.ELK是什么? ELK是由Elasticsearch.Logstash.Kibana这3个软件的缩写. Elasticsearch是一个分布式搜索分析引擎,稳定.可水平扩展.易于管理是它的 ...
- 用SignalR实现实时查看WebAPI请求日志
实现的原理比较直接,定义一个MessageHandler记录WebAPI的请求记录,然后将这些请求日志推送到客户端,客户端就是一个查看日志的页面,实时将请求日志展示在页面中. 这个例子的目的是演示如何 ...
- 使用Python 将shapefile导入mongodb
使用Python 将shapefile导入mongodb 随着big data时代的到来,各个行业都在考虑能不能把big data的思路.方法引入进来,GIS行业也不能免俗. 下面就介绍一下如何将sh ...
- Nginx日志导入到Hive0.13.1,同步Hbase0.96.2,设置RowKey为autoincrement(ID自增长)
---------------------------------------- 博文作者:迦壹 博客地址:Nginx日志导入到Hive,同步Hbase,设置RowKey为autoincrement( ...
随机推荐
- SQL几种常用的函数
函数的种类: 算数函数(数值计算的函数) 字符串函数(字符串操作的函数) 日期函数(用来进行日期操作的函数) 转换函数(用来转换数据类型和值的函数) 聚合函数(用来进行数据聚合的函数) 算数函数(+- ...
- ionic下拉多项选择
1.npm install ion-multi-picker --save 2.引入 import { MultiPickerModule } from 'ion-multi-picker'; imp ...
- JS弹出子窗口
目的 在一个主窗口中,点击一个链接, 弹出一个子窗口 , 父窗口保留 在子窗口中点击关闭, 关闭子窗口. 子窗口的位置位于屏幕的中间 实现 main.html <!DOCTYPE html> ...
- Oracle中的rownum 和rowid的用法和区别
Oracle中的rownum 和rowid的用法和区别 1.rownum是伪列,是在获取查询结果集后再加上去的 (获取一条记录加一个rownum).对符合条件的结果添加一个从1开始的序列号. eg ...
- POJ 3984 迷宫问题 (BFS + Stack)
链接 : Here! 思路 : BFS一下, 然后记录下每个孩子的父亲用于找到一条路径, 因为寻找这条路径只能从后向前找, 这符合栈的特点, 因此在输出路径的时候先把目标节点压入栈中, 然后不断的向前 ...
- Exception总结
NO.1 java.lang.NullPointerException 程序遇上了空指针 NO.2 java.lang.ClassNotFoundException 指定的类不存在 NO.3 java ...
- socket 网络编程笔记 一
初始socket模块 Serve端代码 import socket sk = socket.socket() #默认为TCP连接 """socket 里面两个方法 fam ...
- 并发通信Manage,队列, 互斥锁
目录 Manage 队列 先入先出 互斥锁 Manage 进程间的通信是被限制的 from multiprocessing import Process a = 1 def func(): glob ...
- Dubbo学习总结(2)——Dubbo架构详解
一.前言 部门去年年中开始各种改造,第一步是模块服务化,这边初选dubbo试用在一些非重要模块上,慢慢引入到一些稍微重要的功能上,半年时间,学习过程及线上使用遇到的些问题在此总结下. 整理这篇文章差不 ...
- Divisible Group Sums
Divisible Group Sums Given a list of N numbers you will be allowed to choose any M of them. So you c ...