Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
8
8timerapiv200
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
8timerv2
8timerapiv200
Commits
947dd991
Commit
947dd991
authored
4 years ago
by
ilal
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'develop' of develop-gitlab.youlingrc.com:8timerv2/8timerapiv200 into lal
parents
04fae78a
c2c9de53
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
302 additions
and
0 deletions
+302
-0
src/main/java/cn/timer/api/aspect/RequestAop.java
+211
-0
src/main/resources/logback-spring.xml
+91
-0
No files found.
src/main/java/cn/timer/api/aspect/RequestAop.java
0 → 100644
View file @
947dd991
package
cn
.
timer
.
api
.
aspect
;
import
java.io.PrintWriter
;
import
java.io.StringWriter
;
import
java.text.SimpleDateFormat
;
import
java.util.Date
;
import
java.util.Enumeration
;
import
java.util.TimeZone
;
import
javax.servlet.http.HttpServletRequest
;
import
org.aspectj.lang.JoinPoint
;
import
org.aspectj.lang.ProceedingJoinPoint
;
import
org.aspectj.lang.annotation.Around
;
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.scheduling.annotation.Async
;
import
org.springframework.stereotype.Component
;
import
org.springframework.web.context.request.RequestContextHolder
;
import
org.springframework.web.context.request.ServletRequestAttributes
;
import
com.alibaba.fastjson.JSONArray
;
import
com.alibaba.fastjson.JSONObject
;
import
cn.timer.api.config.exception.CustomException
;
import
lombok.extern.slf4j.Slf4j
;
/**
* 拦截输出异常堆栈(改用fluentd方式)
*
* @author Rex.Tan
* @date 2018年12月13日 上午9:18:58
*/
@Slf4j
@Aspect
@Component
@Order
(
999
)
public
class
RequestAop
{
@Pointcut
(
"execution(* cn.timer..*.*Controller.*(..))"
)
public
void
init
()
{
}
@Before
(
"init()"
)
public
void
beforeAdvice
(
JoinPoint
joinPoint
)
{
// 进入方法前拦截
}
@Around
(
"init()"
)
public
Object
around
(
ProceedingJoinPoint
pjp
)
{
long
startTime
=
System
.
currentTimeMillis
();
HttpServletRequest
request
=
((
ServletRequestAttributes
)
RequestContextHolder
.
getRequestAttributes
()).
getRequest
();
String
url
=
request
.
getRequestURI
();
/**
* 输出url
*/
Object
obj
=
null
;
String
bodyArgs
=
this
.
bodyArgs2String
(
request
,
pjp
.
getArgs
(),
url
);
JSONObject
urlArgs
=
this
.
urlArgs2String
(
request
,
request
.
getParameterNames
(),
url
);
try
{
obj
=
pjp
.
proceed
();
long
endTime
=
System
.
currentTimeMillis
();
this
.
logInfo2Kafka
(
request
,
url
,
bodyArgs
,
urlArgs
,
"success"
,
0
,
endTime
-
startTime
,
true
);
}
catch
(
Throwable
e
)
{
e
.
printStackTrace
();
long
endTime
=
System
.
currentTimeMillis
();
if
(
e
instanceof
CustomException
)
{
/**
* 拦截到主动抛出的异常
*/
CustomException
ex
=
(
CustomException
)
e
;
this
.
logInfo2Kafka
(
request
,
url
,
bodyArgs
,
urlArgs
,
ex
.
getMessage
(),
400
,
endTime
-
startTime
,
false
);
throw
ex
;
}
else
{
/**
* 拦截到未知异常
*/
StringWriter
stringWriter
=
new
StringWriter
();
e
.
printStackTrace
(
new
PrintWriter
(
stringWriter
));
this
.
logInfo2Kafka
(
request
,
url
,
bodyArgs
,
urlArgs
,
"未捕获异常: "
+
stringWriter
.
toString
(),
500
,
endTime
-
startTime
,
false
);
throw
new
CustomException
(
"未捕获异常,"
+
e
.
getMessage
());
}
}
finally
{
}
return
obj
;
}
/**
* 请录请求耗时
*
* @author Rex.Tan
* @date 2018年12月13日 下午2:51:31
* @param url 请求地址
* @param args requestBody中的参数
* @param args2 url中的参数
* @param message 消息
* @param status 接口调用返回状态
* @param executionTime 执行耗时
* @param isSuccess 是否调用成功
*/
@Async
public
void
logInfo2Kafka
(
HttpServletRequest
request
,
String
url
,
String
bodyArgs
,
JSONObject
urlArgs
,
String
message
,
Integer
status
,
long
executionTime
,
boolean
isSuccess
)
{
JSONObject
json
=
new
JSONObject
();
json
.
put
(
"logType"
,
"___rest___"
);
// if (UserContext.get() != null) {
// json.put("userName", UserContext.get().getUsername());
// }
json
.
put
(
"url"
,
url
);
json
.
put
(
"timestamp"
,
System
.
currentTimeMillis
());
json
.
put
(
"visitTime"
,
now2String
());
json
.
put
(
"message"
,
message
);
json
.
put
(
"status"
,
status
);
json
.
put
(
"executionTime"
,
executionTime
);
json
.
put
(
"channel"
,
request
.
getHeader
(
"channel"
));
json
.
put
(
"projectName"
,
"8timer"
);
json
.
put
(
"requestType"
,
request
.
getMethod
());
/**
* 1.requestBody中的参数
*/
json
.
put
(
"bodyArgs"
,
bodyArgs
);
/**
* 2.url中的参数
*/
json
.
put
(
"urlArgs"
,
urlArgs
);
/**
* 3.如果请求状态不为0, 在控制台输入请求信息
*/
if
(
status
!=
0
)
{
log
.
error
(
"\r\n"
+
json
.
toJSONString
());
}
else
{
log
.
info
(
"\r\n"
+
json
.
toJSONString
());
}
}
/**
* 读取requestBody中的参数
*
* @author Rex.Tan
* @date 2018年12月13日 下午2:54:31
* @param bodyArgs
* @param url
* @return
*/
private
String
bodyArgs2String
(
HttpServletRequest
request
,
Object
[]
bodyArgs
,
String
url
)
{
if
(
"GET"
.
equals
(
request
.
getMethod
()))
{
return
""
;
}
if
(
url
!=
null
&&
url
.
matches
(
"upload"
))
{
return
""
;
}
if
(
url
!=
null
&&
url
.
matches
(
"image"
))
{
return
""
;
}
try
{
if
(
bodyArgs
!=
null
&&
bodyArgs
.
length
>
0
)
{
String
body
=
JSONArray
.
toJSONString
(
bodyArgs
);
if
(
body
.
matches
(
"image"
))
{
return
""
;
}
return
body
;
}
}
catch
(
Exception
e
)
{
log
.
error
(
"=============序列化requestBody中的参数出错, "
+
url
);
}
return
""
;
}
/**
* 读取url中的参数
*
* @author Rex.Tan
* @date 2019年9月12日 下午2:54:40
* @param request
* @param urlArgs
* @param url
* @return
*/
private
JSONObject
urlArgs2String
(
HttpServletRequest
request
,
Enumeration
<
String
>
urlArgs
,
String
url
)
{
JSONObject
urlArgsJson
=
new
JSONObject
();
try
{
if
(
urlArgs
!=
null
)
{
while
(
urlArgs
.
hasMoreElements
())
{
try
{
String
paraName
=
(
String
)
urlArgs
.
nextElement
();
urlArgsJson
.
put
(
paraName
,
request
.
getParameter
(
paraName
));
}
catch
(
Exception
e
)
{
log
.
error
(
"=============记录url中的参数出错"
,
url
);
break
;
}
}
}
}
catch
(
Exception
e
)
{
log
.
error
(
"=============记录url中的参数出错, "
+
url
);
}
return
urlArgsJson
;
}
private
static
String
now2String
()
{
SimpleDateFormat
sdf
=
new
SimpleDateFormat
(
"yyyy-MM-dd HH:mm:ss"
);
sdf
.
setTimeZone
(
TimeZone
.
getTimeZone
(
"Asia/Shanghai"
));
Date
now
=
new
Date
();
return
sdf
.
format
(
now
);
}
}
This diff is collapsed.
Click to expand it.
src/main/resources/logback-spring.xml
0 → 100644
View file @
947dd991
<?xml version="1.0" encoding="UTF-8"?>
<configuration
scan=
"true"
scanPeriod=
"60 seconds"
debug=
"false"
>
<!--2、设置上下文名称 每个logger都关联到logger上下文,默认上下文名称为“default”。但可以使用设置成其他名字,用于区分不同应用程序的记录。
一旦设置,不能修改,可以通过 %contextName 来打印日志上下文名称,一般来说我们不用这个属性,可有可无。 -->
<!--<contextName>cool_is_life</contextName> -->
<!--3、设置变量 用来定义变量值的标签, 有两个属性,name和value;其中name的值是变量的名称,value的值时变量定义的值。 通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 -->
<!--<property name="log.path" value="/logs/logback.log" /> -->
<!--<property name="log.path" value="/logs/logback" /> -->
<property
name=
"logback.logdir"
value=
"/deploy/logs/"
/>
<property
name=
"logback.appname"
value=
"8timer-api"
/>
<!--4、appender用来格式化日志输出节点,有俩个属性name和class,class用来指定哪种输出策略,常用就是控制台输出策略和文件输出策略。
控制台输出 ConsoleAppender 输出到文件 RollingFileAppender -->
<!--输出到控制台 -->
<appender
name=
"console"
class=
"ch.qos.logback.core.ConsoleAppender"
>
<encoder>
<pattern>
%d{YYYY-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger - %msg%n
</pattern>
<charset>
UTF-8
</charset>
</encoder>
</appender>
<!--输出到文件 -->
<appender
name=
"file"
class=
"ch.qos.logback.core.rolling.RollingFileAppender"
>
<!--如果只是想要 Info 级别的日志,只是过滤 info 还是会输出 Error 日志,因为 Error 的级别高,所以我们使用下面的策略,可以避免输出
Error 的日志 -->
<filter
class=
"ch.qos.logback.classic.filter.LevelFilter"
>
<!--过滤 Error -->
<level>
ERROR
</level>
<!--匹配到就禁止 -->
<onMatch>
DENY
</onMatch>
<!--没有匹配到就允许 -->
<onMismatch>
ACCEPT
</onMismatch>
</filter>
<!--日志名称,如果没有File 属性,那么只会使用FileNamePattern的文件路径规则,如果同时有<File>和<FileNamePattern>,那么当天日志是<File>,明天会自动把今天
的日志改名为今天的日期。即,<File> 的日志都是当天的。 -->
<file>
${logback.logdir}/${logback.appname}.info.log
</file>
<!--滚动策略,按照时间滚动 TimeBasedRollingPolicy -->
<rollingPolicy
class=
"ch.qos.logback.core.rolling.TimeBasedRollingPolicy"
>
<!--文件路径,定义了日志的切分方式——把每一天的日志归档到一个文件中,以防止日志填满整个磁盘空间 -->
<FileNamePattern>
${logback.logdir}/bak/${logback.appname}.info.%d{yyyy-MM-dd}.%i.log
</FileNamePattern>
<!--只保留最近7天的日志 -->
<maxHistory>
7
</maxHistory>
<!--用来指定日志文件的上限大小,那么到了这个值,就会删除旧的日志 -->
<totalSizeCap>
1GB
</totalSizeCap>
<timeBasedFileNamingAndTriggeringPolicy
class=
"ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"
>
<maxFileSize>
100MB
</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<pattern>
%d{YYYY-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger - %msg%n
</pattern>
</encoder>
</appender>
<appender
name=
"fileErrorLog"
class=
"ch.qos.logback.core.rolling.RollingFileAppender"
>
<!--如果只是想要 Error 级别的日志,那么需要过滤一下,默认是 info 级别的,ThresholdFilter -->
<filter
class=
"ch.qos.logback.classic.filter.ThresholdFilter"
>
<level>
error
</level>
</filter>
<!--日志名称,如果没有File 属性,那么只会使用FileNamePattern的文件路径规则 如果同时有<File>和<FileNamePattern>,那么当天日志是<File>,明天会自动把今天
的日志改名为今天的日期。即,<File> 的日志都是当天的。 -->
<File>
${logback.logdir}/${logback.appname}.error.log
</File>
<!--滚动策略,按照时间滚动 TimeBasedRollingPolicy -->
<rollingPolicy
class=
"ch.qos.logback.core.rolling.TimeBasedRollingPolicy"
>
<!--文件路径,定义了日志的切分方式——把每一天的日志归档到一个文件中,以防止日志填满整个磁盘空间 -->
<FileNamePattern>
${logback.logdir}/bak/${logback.appname}.error.%d{yyyy-MM-dd}.%i.log
</FileNamePattern>
<!--只保留最近7天的日志 -->
<maxHistory>
7
</maxHistory>
<!--用来指定日志文件的上限大小,那么到了这个值,就会删除旧的日志 -->
<!--<totalSizeCap>1GB</totalSizeCap> -->
<timeBasedFileNamingAndTriggeringPolicy
class=
"ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"
>
<maxFileSize>
100MB
</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<!--日志输出编码格式化 -->
<encoder>
<charset>
UTF-8
</charset>
<pattern>
%d [%thread] %-5level %logger{36} %line - %msg%n
</pattern>
</encoder>
</appender>
<!--1、root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性。 level:用来设置打印级别,大小写无关:TRACE,
DEBUG, INFO, WARN, ERROR, ALL 和 OFF,不能设置为INHERITED或者同义词NULL。 默认是DEBUG。 可以包含零个或多个元素,标识这个appender将会添加到这个loger。 -->
<root
level=
"INFO"
>
<appender-ref
ref=
"console"
/>
<appender-ref
ref=
"file"
/>
<appender-ref
ref=
"fileErrorLog"
/>
</root>
</configuration>
\ No newline at end of file
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment