使用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( ...
随机推荐
- CDR服装设计-用CorelDRAW排钻如何把圈摆均匀
服装设计一直都是一个很火热的行业,也是一个比较高端的行业,随着时代的步伐,以前的人都是用手绘的方式来设计服装,现在不一样了,电脑可以说普及到了每一个家庭,让软件以更快的速度,更准确的数据来设计服装中的 ...
- ionic 创建某个文件下的page
ionic g page 文件名 --pagesDir src/pages/about
- 2019 支付宝App支付 --- PHP
SDK下载:https://docs.open.alipay.com/54/106370/;联系客服:https://cschannel.alipay.com/newPortal.htm?scene= ...
- SQL一对多取子表最新记录的所有字段(ROW_NUMBER()OVER()函数的应用)
ROW_NUMBER()OVER() 参数1:分组字段 PARTITION BY ..,..,.... 可选 参数2:排序字段 ORDER BY .. DESC 必须 实例: 根据Confir ...
- wing ide破解
LicenseID='CN123-12345-12345-67891' # RequestCode='RL634-8363J-X7E8K-95XD3' RequestCode = 'RW61C-NN6 ...
- NTP测试1
ntp server A : 10.101.75.8 B : 10.101.75.38 B: [root@r10n16313.sqa.zmf /home/ahao.mah] #cat /etc/ntp ...
- php第十九节课
JQUERY <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www. ...
- js-2018-11-01 关于break和continue语句
1.label语句 语法:label: statement 加标签语句一般都要与for语句等循环语句配合使用. 2.break语句 立即退出循环,强制执行循环后面的语句. 3.continue语句 立 ...
- char如何储存3个字节或者4个字节
1.char字符存储的是Unicode编码的代码点,也就是存储的是U+FF00这样的数值,然而我们在调试或者输出到输出流的时候,是JVM或者开发工具按照代码点对应的编码字符输出的. 2. 所以虽然UT ...
- (转)window.location.hash 属性使用说明
location是javascript里边管理地址栏的内置对象,比如location.href就管理页面的url,用location.href=url就可以直接将页面重定向url.而location. ...