Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
S
shop
Project
Project
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
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
曲欣亮
shop
Commits
55b81ab3
Commit
55b81ab3
authored
Aug 31, 2019
by
Quxl
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
增加Druid数据源监控
parent
f57d2e18
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
438 additions
and
6 deletions
+438
-6
pom.xml
pom.xml
+5
-6
WebStatFilter.java
...in/java/com/alibaba/druid/support/http/WebStatFilter.java
+359
-0
DruidConfig.java
src/main/java/com/egolm/shop/config/DruidConfig.java
+71
-0
application-dev.properties
src/main/resources/application-dev.properties
+1
-0
application-pro.properties
src/main/resources/application-pro.properties
+1
-0
application-test.properties
src/main/resources/application-test.properties
+1
-0
No files found.
pom.xml
View file @
55b81ab3
...
@@ -38,13 +38,17 @@
...
@@ -38,13 +38,17 @@
<dependency>
<dependency>
<groupId>
mysql
</groupId>
<groupId>
mysql
</groupId>
<artifactId>
mysql-connector-java
</artifactId>
<artifactId>
mysql-connector-java
</artifactId>
</dependency>
<dependency>
<groupId>
com.alibaba
</groupId>
<artifactId>
druid-spring-boot-starter
</artifactId>
<version>
1.1.20
</version>
</dependency>
</dependency>
<dependency>
<dependency>
<groupId>
com.microsoft.sqlserver
</groupId>
<groupId>
com.microsoft.sqlserver
</groupId>
<artifactId>
sqljdbc4
</artifactId>
<artifactId>
sqljdbc4
</artifactId>
<version>
4.0
</version>
<version>
4.0
</version>
</dependency>
</dependency>
<dependency>
<dependency>
<groupId>
com.alibaba
</groupId>
<groupId>
com.alibaba
</groupId>
<artifactId>
fastjson
</artifactId>
<artifactId>
fastjson
</artifactId>
...
@@ -55,11 +59,6 @@
...
@@ -55,11 +59,6 @@
<artifactId>
common
</artifactId>
<artifactId>
common
</artifactId>
<version>
0.0.1-RELEASE
</version>
<version>
0.0.1-RELEASE
</version>
</dependency>
</dependency>
<dependency>
<groupId>
com.alibaba
</groupId>
<artifactId>
druid
</artifactId>
<version>
1.1.6
</version>
</dependency>
<dependency>
<dependency>
<groupId>
io.springfox
</groupId>
<groupId>
io.springfox
</groupId>
<artifactId>
springfox-swagger2
</artifactId>
<artifactId>
springfox-swagger2
</artifactId>
...
...
src/main/java/com/alibaba/druid/support/http/WebStatFilter.java
0 → 100644
View file @
55b81ab3
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
com
.
alibaba
.
druid
.
support
.
http
;
import
java.io.IOException
;
import
java.util.Arrays
;
import
java.util.HashSet
;
import
java.util.Map
;
import
java.util.Set
;
import
javax.servlet.Filter
;
import
javax.servlet.FilterChain
;
import
javax.servlet.FilterConfig
;
import
javax.servlet.ServletException
;
import
javax.servlet.ServletRequest
;
import
javax.servlet.ServletResponse
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
javax.servlet.http.HttpServletResponseWrapper
;
import
com.alibaba.druid.filter.stat.StatFilterContext
;
import
com.alibaba.druid.support.http.stat.WebAppStat
;
import
com.alibaba.druid.support.http.stat.WebAppStatManager
;
import
com.alibaba.druid.support.http.stat.WebRequestStat
;
import
com.alibaba.druid.support.http.stat.WebSessionStat
;
import
com.alibaba.druid.support.http.stat.WebURIStat
;
import
com.alibaba.druid.support.logging.Log
;
import
com.alibaba.druid.support.logging.LogFactory
;
import
com.alibaba.druid.support.profile.ProfileEntryKey
;
import
com.alibaba.druid.support.profile.ProfileEntryReqStat
;
import
com.alibaba.druid.support.profile.Profiler
;
import
com.alibaba.druid.util.DruidWebUtils
;
import
com.alibaba.druid.util.PatternMatcher
;
import
com.alibaba.druid.util.ServletPathMatcher
;
/**
* 用于配置Web和Druid数据源之间的管理关联监控统计
*
* @author wenshao [szujobs@htomail.com]
* @author Zhangming Qi [qizhanming@gmail.com]
*/
public
class
WebStatFilter
extends
AbstractWebStatImpl
implements
Filter
{
private
final
static
Log
LOG
=
LogFactory
.
getLog
(
WebStatFilter
.
class
);
public
final
static
String
PARAM_NAME_PROFILE_ENABLE
=
"profileEnable"
;
public
final
static
String
PARAM_NAME_SESSION_STAT_ENABLE
=
"sessionStatEnable"
;
public
final
static
String
PARAM_NAME_SESSION_STAT_MAX_COUNT
=
"sessionStatMaxCount"
;
public
static
final
String
PARAM_NAME_EXCLUSIONS
=
"exclusions"
;
public
static
final
String
PARAM_NAME_PRINCIPAL_SESSION_NAME
=
"principalSessionName"
;
public
static
final
String
PARAM_NAME_PRINCIPAL_COOKIE_NAME
=
"principalCookieName"
;
public
static
final
String
PARAM_NAME_REAL_IP_HEADER
=
"realIpHeader"
;
/**
* PatternMatcher used in determining which paths to react to for a given request.
*/
protected
PatternMatcher
pathMatcher
=
new
ServletPathMatcher
();
private
Set
<
String
>
excludesPattern
;
@Override
public
void
doFilter
(
ServletRequest
request
,
ServletResponse
response
,
FilterChain
chain
)
throws
IOException
,
ServletException
{
HttpServletRequest
httpRequest
=
(
HttpServletRequest
)
request
;
HttpServletResponse
httpResponse
=
(
HttpServletResponse
)
response
;
StatHttpServletResponseWrapper
responseWrapper
=
new
StatHttpServletResponseWrapper
(
httpResponse
);
String
requestURI
=
getRequestURI
(
httpRequest
);
for
(
String
pName
:
new
String
[]{
"queryName"
,
"BusinessID"
,
"objectName"
})
{
String
value
=
request
.
getParameter
(
pName
);
if
(
value
!=
null
&&
value
.
trim
().
length
()
>
0
)
{
requestURI
+=
"/"
+
pName
+
"/"
+
value
;
}
}
requestURI
=
requestURI
.
replaceAll
(
"/+"
,
"/"
);
if
(
isExclusion
(
requestURI
))
{
chain
.
doFilter
(
request
,
response
);
return
;
}
long
startNano
=
System
.
nanoTime
();
long
startMillis
=
System
.
currentTimeMillis
();
WebRequestStat
requestStat
=
new
WebRequestStat
(
startNano
,
startMillis
);
WebRequestStat
.
set
(
requestStat
);
WebSessionStat
sessionStat
=
getSessionStat
(
httpRequest
);
webAppStat
.
beforeInvoke
();
WebURIStat
uriStat
=
webAppStat
.
getURIStat
(
requestURI
,
false
);
if
(
uriStat
==
null
)
{
int
index
=
requestURI
.
indexOf
(
";jsessionid="
);
if
(
index
!=
-
1
)
{
requestURI
=
requestURI
.
substring
(
0
,
index
);
uriStat
=
webAppStat
.
getURIStat
(
requestURI
,
false
);
}
}
if
(
isProfileEnable
())
{
Profiler
.
initLocal
();
Profiler
.
enter
(
requestURI
,
Profiler
.
PROFILE_TYPE_WEB
);
}
// 第一次访问时,uriStat这里为null,是为了防止404攻击。
if
(
uriStat
!=
null
)
{
uriStat
.
beforeInvoke
();
}
// 第一次访问时,sessionId为null,如果缺省sessionCreate=false,sessionStat就为null。
if
(
sessionStat
!=
null
)
{
sessionStat
.
beforeInvoke
();
}
Throwable
error
=
null
;
try
{
chain
.
doFilter
(
request
,
responseWrapper
);
}
catch
(
IOException
e
)
{
error
=
e
;
throw
e
;
}
catch
(
ServletException
e
)
{
error
=
e
;
throw
e
;
}
catch
(
RuntimeException
e
)
{
error
=
e
;
throw
e
;
}
catch
(
Error
e
)
{
error
=
e
;
throw
e
;
}
finally
{
long
endNano
=
System
.
nanoTime
();
requestStat
.
setEndNano
(
endNano
);
long
nanos
=
endNano
-
startNano
;
webAppStat
.
afterInvoke
(
error
,
nanos
);
if
(
sessionStat
==
null
)
{
sessionStat
=
getSessionStat
(
httpRequest
);
if
(
sessionStat
!=
null
)
{
sessionStat
.
beforeInvoke
();
// 补偿
}
}
if
(
sessionStat
!=
null
)
{
sessionStat
.
afterInvoke
(
error
,
nanos
);
sessionStat
.
setPrincipal
(
getPrincipal
(
httpRequest
));
}
if
(
uriStat
==
null
)
{
int
status
=
responseWrapper
.
getStatus
();
if
(
status
==
HttpServletResponse
.
SC_NOT_FOUND
)
{
String
errorUrl
=
contextPath
+
"error_"
+
status
;
uriStat
=
webAppStat
.
getURIStat
(
errorUrl
,
true
);
}
else
{
uriStat
=
webAppStat
.
getURIStat
(
requestURI
,
true
);
}
if
(
uriStat
!=
null
)
{
uriStat
.
beforeInvoke
();
// 补偿调用
}
}
if
(
uriStat
!=
null
)
{
uriStat
.
afterInvoke
(
error
,
nanos
);
}
WebRequestStat
.
set
(
null
);
if
(
isProfileEnable
())
{
Profiler
.
release
(
nanos
);
Map
<
ProfileEntryKey
,
ProfileEntryReqStat
>
requestStatsMap
=
Profiler
.
getStatsMap
();
if
(
uriStat
!=
null
)
{
uriStat
.
getProfiletat
().
record
(
requestStatsMap
);
}
Profiler
.
removeLocal
();
}
}
}
public
boolean
isExclusion
(
String
requestURI
)
{
if
(
excludesPattern
==
null
||
requestURI
==
null
)
{
return
false
;
}
if
(
contextPath
!=
null
&&
requestURI
.
startsWith
(
contextPath
))
{
requestURI
=
requestURI
.
substring
(
contextPath
.
length
());
if
(!
requestURI
.
startsWith
(
"/"
))
{
requestURI
=
"/"
+
requestURI
;
}
}
for
(
String
pattern
:
excludesPattern
)
{
if
(
pathMatcher
.
matches
(
pattern
,
requestURI
))
{
return
true
;
}
}
return
false
;
}
@Override
public
void
init
(
FilterConfig
config
)
throws
ServletException
{
{
String
exclusions
=
config
.
getInitParameter
(
PARAM_NAME_EXCLUSIONS
);
if
(
exclusions
!=
null
&&
exclusions
.
trim
().
length
()
!=
0
)
{
excludesPattern
=
new
HashSet
<
String
>(
Arrays
.
asList
(
exclusions
.
split
(
"\\s*,\\s*"
)));
}
}
{
String
param
=
config
.
getInitParameter
(
PARAM_NAME_PRINCIPAL_SESSION_NAME
);
if
(
param
!=
null
)
{
param
=
param
.
trim
();
if
(
param
.
length
()
!=
0
)
{
this
.
principalSessionName
=
param
;
}
}
}
{
String
param
=
config
.
getInitParameter
(
PARAM_NAME_PRINCIPAL_COOKIE_NAME
);
if
(
param
!=
null
)
{
param
=
param
.
trim
();
if
(
param
.
length
()
!=
0
)
{
this
.
principalCookieName
=
param
;
}
}
}
{
String
param
=
config
.
getInitParameter
(
PARAM_NAME_SESSION_STAT_ENABLE
);
if
(
param
!=
null
&&
param
.
trim
().
length
()
!=
0
)
{
param
=
param
.
trim
();
if
(
"true"
.
equals
(
param
))
{
this
.
sessionStatEnable
=
true
;
}
else
if
(
"false"
.
equals
(
param
))
{
this
.
sessionStatEnable
=
false
;
}
else
{
LOG
.
error
(
"WebStatFilter Parameter '"
+
PARAM_NAME_SESSION_STAT_ENABLE
+
"' config error"
);
}
}
}
{
String
param
=
config
.
getInitParameter
(
PARAM_NAME_PROFILE_ENABLE
);
if
(
param
!=
null
&&
param
.
trim
().
length
()
!=
0
)
{
param
=
param
.
trim
();
if
(
"true"
.
equals
(
param
))
{
this
.
profileEnable
=
true
;
}
else
if
(
"false"
.
equals
(
param
))
{
this
.
profileEnable
=
false
;
}
else
{
LOG
.
error
(
"WebStatFilter Parameter '"
+
PARAM_NAME_PROFILE_ENABLE
+
"' config error"
);
}
}
}
{
String
param
=
config
.
getInitParameter
(
PARAM_NAME_SESSION_STAT_MAX_COUNT
);
if
(
param
!=
null
&&
param
.
trim
().
length
()
!=
0
)
{
param
=
param
.
trim
();
try
{
this
.
sessionStatMaxCount
=
Integer
.
parseInt
(
param
);
}
catch
(
NumberFormatException
e
)
{
LOG
.
error
(
"WebStatFilter Parameter '"
+
PARAM_NAME_SESSION_STAT_ENABLE
+
"' config error"
,
e
);
}
}
}
// realIpHeader
{
String
param
=
config
.
getInitParameter
(
PARAM_NAME_REAL_IP_HEADER
);
if
(
param
!=
null
)
{
param
=
param
.
trim
();
if
(
param
.
length
()
!=
0
)
{
this
.
realIpHeader
=
param
;
}
}
}
StatFilterContext
.
getInstance
().
addContextListener
(
statFilterContextListener
);
this
.
contextPath
=
DruidWebUtils
.
getContextPath
(
config
.
getServletContext
());
if
(
webAppStat
==
null
)
{
webAppStat
=
new
WebAppStat
(
contextPath
,
this
.
sessionStatMaxCount
);
}
WebAppStatManager
.
getInstance
().
addWebAppStatSet
(
webAppStat
);
}
@Override
public
void
destroy
()
{
StatFilterContext
.
getInstance
().
removeContextListener
(
statFilterContextListener
);
if
(
webAppStat
!=
null
)
{
WebAppStatManager
.
getInstance
().
remove
(
webAppStat
);
}
}
public
void
setWebAppStat
(
WebAppStat
webAppStat
)
{
this
.
webAppStat
=
webAppStat
;
}
public
WebAppStat
getWebAppStat
()
{
return
webAppStat
;
}
public
WebStatFilterContextListener
getStatFilterContextListener
()
{
return
statFilterContextListener
;
}
public
final
static
class
StatHttpServletResponseWrapper
extends
HttpServletResponseWrapper
implements
HttpServletResponse
{
//初始值应该设置为:HttpServletResponse.SC_OK,而不是 0。
private
int
status
=
HttpServletResponse
.
SC_OK
;
public
StatHttpServletResponseWrapper
(
HttpServletResponse
response
){
super
(
response
);
}
public
void
setStatus
(
int
statusCode
)
{
super
.
setStatus
(
statusCode
);
this
.
status
=
statusCode
;
}
@SuppressWarnings
(
"deprecation"
)
public
void
setStatus
(
int
statusCode
,
String
statusMessage
)
{
super
.
setStatus
(
statusCode
,
statusMessage
);
this
.
status
=
statusCode
;
}
public
void
sendError
(
int
statusCode
,
String
statusMessage
)
throws
IOException
{
super
.
sendError
(
statusCode
,
statusMessage
);
this
.
status
=
statusCode
;
}
public
void
sendError
(
int
statusCode
)
throws
IOException
{
super
.
sendError
(
statusCode
);
this
.
status
=
statusCode
;
}
public
int
getStatus
()
{
return
status
;
}
}
}
src/main/java/com/egolm/shop/config/DruidConfig.java
0 → 100644
View file @
55b81ab3
package
com
.
egolm
.
shop
.
config
;
import
java.io.IOException
;
import
javax.servlet.Filter
;
import
javax.servlet.FilterChain
;
import
javax.servlet.ServletException
;
import
javax.servlet.ServletRequest
;
import
javax.servlet.ServletResponse
;
import
org.springframework.boot.autoconfigure.AutoConfigureAfter
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication
;
import
org.springframework.boot.web.servlet.FilterRegistrationBean
;
import
org.springframework.boot.web.servlet.ServletRegistrationBean
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
;
import
com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties
;
import
com.alibaba.druid.support.http.StatViewServlet
;
import
com.alibaba.druid.support.http.WebStatFilter
;
import
com.alibaba.druid.util.Utils
;
@Configuration
@ConditionalOnWebApplication
@AutoConfigureAfter
(
DruidDataSourceAutoConfigure
.
class
)
@ConditionalOnProperty
(
name
=
"spring.datasource.druid.stat-view-servlet.enabled"
,
havingValue
=
"true"
,
matchIfMissing
=
true
)
public
class
DruidConfig
{
@Bean
public
FilterRegistrationBean
<
Filter
>
bannerFilterRegistrationBean
(
DruidStatProperties
properties
)
{
DruidStatProperties
.
StatViewServlet
config
=
properties
.
getStatViewServlet
();
String
pattern
=
config
.
getUrlPattern
()
!=
null
?
config
.
getUrlPattern
()
:
"/druid/*"
;
String
commonJsPattern
=
pattern
.
replaceAll
(
"\\*"
,
"js/common.js"
);
final
String
filePath
=
"support/http/resources/js/common.js"
;
Filter
filter
=
new
Filter
()
{
@Override
public
void
doFilter
(
ServletRequest
request
,
ServletResponse
response
,
FilterChain
chain
)
throws
IOException
,
ServletException
{
chain
.
doFilter
(
request
,
response
);
response
.
resetBuffer
();
String
text
=
Utils
.
readFromResource
(
filePath
);
text
=
text
.
replaceAll
(
"<a.*?banner\"></a><br/>"
,
""
);
text
=
text
.
replaceAll
(
"powered.*?shrek.wang</a>"
,
""
);
response
.
getWriter
().
write
(
text
);
}
};
FilterRegistrationBean
<
Filter
>
registrationBean
=
new
FilterRegistrationBean
<
Filter
>();
registrationBean
.
setFilter
(
filter
);
registrationBean
.
addUrlPatterns
(
commonJsPattern
);
return
registrationBean
;
}
@Bean
public
FilterRegistrationBean
<
Filter
>
webStatFilterRegistrationBean
(
DruidStatProperties
properties
)
{
WebStatFilter
filter
=
new
WebStatFilter
();
FilterRegistrationBean
<
Filter
>
registrationBean
=
new
FilterRegistrationBean
<
Filter
>();
registrationBean
.
setFilter
(
filter
);
registrationBean
.
addUrlPatterns
(
"/*"
);
registrationBean
.
addInitParameter
(
"exclusions"
,
"*.js, *.gif, *.jpg, *.bmp, *.png, *.css, *.ico, /druid/*"
);
return
registrationBean
;
}
@Bean
public
ServletRegistrationBean
<?>
setvletRegistrationBean
()
{
ServletRegistrationBean
<
StatViewServlet
>
setvletRegistrationBean
=
new
ServletRegistrationBean
<
StatViewServlet
>(
new
StatViewServlet
(),
"/druid/*"
);
setvletRegistrationBean
.
addInitParameter
(
"resetEnable"
,
"true"
);
return
setvletRegistrationBean
;
}
}
src/main/resources/application-dev.properties
View file @
55b81ab3
...
@@ -20,6 +20,7 @@ spring.datasource.testWhileIdle=true
...
@@ -20,6 +20,7 @@ spring.datasource.testWhileIdle=true
spring.datasource.validationQueryTimeout
=
5
spring.datasource.validationQueryTimeout
=
5
spring.datasource.validationQuery
=
SELECT 1
spring.datasource.validationQuery
=
SELECT 1
spring.datasource.timeBetweenEvictionRunsMillis
=
3600000
spring.datasource.timeBetweenEvictionRunsMillis
=
3600000
spring.datasource.filters
=
stat,wall,log4j
spring.redis.database
=
0
spring.redis.database
=
0
...
...
src/main/resources/application-pro.properties
View file @
55b81ab3
...
@@ -20,6 +20,7 @@ spring.datasource.testWhileIdle=true
...
@@ -20,6 +20,7 @@ spring.datasource.testWhileIdle=true
spring.datasource.validationQueryTimeout
=
5
spring.datasource.validationQueryTimeout
=
5
spring.datasource.validationQuery
=
SELECT 1
spring.datasource.validationQuery
=
SELECT 1
spring.datasource.timeBetweenEvictionRunsMillis
=
3600000
spring.datasource.timeBetweenEvictionRunsMillis
=
3600000
spring.datasource.filters
=
stat,wall,log4j
spring.redis.database
=
0
spring.redis.database
=
0
...
...
src/main/resources/application-test.properties
View file @
55b81ab3
...
@@ -20,6 +20,7 @@ spring.datasource.testWhileIdle=true
...
@@ -20,6 +20,7 @@ spring.datasource.testWhileIdle=true
spring.datasource.validationQueryTimeout
=
5
spring.datasource.validationQueryTimeout
=
5
spring.datasource.validationQuery
=
SELECT 1
spring.datasource.validationQuery
=
SELECT 1
spring.datasource.timeBetweenEvictionRunsMillis
=
3600000
spring.datasource.timeBetweenEvictionRunsMillis
=
3600000
spring.datasource.filters
=
stat,wall,log4j
spring.redis.database
=
0
spring.redis.database
=
0
...
...
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