Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in / Register
Toggle navigation
S
spring-boot
Project
Project
Details
Activity
Releases
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
DEMO
spring-boot
Commits
37fa3a3b
Commit
37fa3a3b
authored
Apr 06, 2016
by
Phillip Webb
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #5102 from sebastiankirsch
* gh-4913: Allow per-http-method MetricsFilter submissions
parents
40e51021
a15684e6
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
220 additions
and
5 deletions
+220
-5
MetricFilterAutoConfiguration.java
.../actuate/autoconfigure/MetricFilterAutoConfiguration.java
+8
-2
MetricFilterProperties.java
...rk/boot/actuate/autoconfigure/MetricFilterProperties.java
+81
-0
MetricsFilter.java
...ngframework/boot/actuate/autoconfigure/MetricsFilter.java
+21
-3
MetricsFilterSubmission.java
...k/boot/actuate/autoconfigure/MetricsFilterSubmission.java
+38
-0
MetricFilterAutoConfigurationTests.java
...ate/autoconfigure/MetricFilterAutoConfigurationTests.java
+70
-0
appendix-application-properties.adoc
...cs/src/main/asciidoc/appendix-application-properties.adoc
+2
-0
No files found.
spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/MetricFilterAutoConfiguration.java
View file @
37fa3a3b
...
@@ -26,6 +26,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
...
@@ -26,6 +26,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnBean
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnBean
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnClass
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnClass
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
;
import
org.springframework.boot.context.properties.EnableConfigurationProperties
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.web.filter.OncePerRequestFilter
;
import
org.springframework.web.filter.OncePerRequestFilter
;
...
@@ -38,6 +39,7 @@ import org.springframework.web.servlet.HandlerMapping;
...
@@ -38,6 +39,7 @@ import org.springframework.web.servlet.HandlerMapping;
* @author Dave Syer
* @author Dave Syer
* @author Phillip Webb
* @author Phillip Webb
* @author Andy Wilkinson
* @author Andy Wilkinson
* @author Sebastian Kirsch
*/
*/
@Configuration
@Configuration
@ConditionalOnBean
({
CounterService
.
class
,
GaugeService
.
class
})
@ConditionalOnBean
({
CounterService
.
class
,
GaugeService
.
class
})
...
@@ -45,21 +47,25 @@ import org.springframework.web.servlet.HandlerMapping;
...
@@ -45,21 +47,25 @@ import org.springframework.web.servlet.HandlerMapping;
OncePerRequestFilter
.
class
,
HandlerMapping
.
class
})
OncePerRequestFilter
.
class
,
HandlerMapping
.
class
})
@AutoConfigureAfter
(
MetricRepositoryAutoConfiguration
.
class
)
@AutoConfigureAfter
(
MetricRepositoryAutoConfiguration
.
class
)
@ConditionalOnProperty
(
name
=
"endpoints.metrics.filter.enabled"
,
matchIfMissing
=
true
)
@ConditionalOnProperty
(
name
=
"endpoints.metrics.filter.enabled"
,
matchIfMissing
=
true
)
@EnableConfigurationProperties
({
MetricFilterProperties
.
class
})
public
class
MetricFilterAutoConfiguration
{
public
class
MetricFilterAutoConfiguration
{
private
final
CounterService
counterService
;
private
final
CounterService
counterService
;
private
final
GaugeService
gaugeService
;
private
final
GaugeService
gaugeService
;
private
final
MetricFilterProperties
properties
;
public
MetricFilterAutoConfiguration
(
CounterService
counterService
,
public
MetricFilterAutoConfiguration
(
CounterService
counterService
,
GaugeService
gaugeService
)
{
GaugeService
gaugeService
,
MetricFilterProperties
properties
)
{
this
.
counterService
=
counterService
;
this
.
counterService
=
counterService
;
this
.
gaugeService
=
gaugeService
;
this
.
gaugeService
=
gaugeService
;
this
.
properties
=
properties
;
}
}
@Bean
@Bean
public
MetricsFilter
metricFilter
()
{
public
MetricsFilter
metricFilter
()
{
return
new
MetricsFilter
(
this
.
counterService
,
this
.
gaugeService
);
return
new
MetricsFilter
(
this
.
counterService
,
this
.
gaugeService
,
this
.
properties
);
}
}
}
}
spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/MetricFilterProperties.java
0 → 100644
View file @
37fa3a3b
/*
* Copyright 2012-2016 the original author or authors.
*
* 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
org
.
springframework
.
boot
.
actuate
.
autoconfigure
;
import
java.util.EnumSet
;
import
java.util.HashSet
;
import
java.util.Set
;
import
org.springframework.boot.context.properties.ConfigurationProperties
;
/**
* Configuration properties for the {@link MetricsFilter}.
*
* @author Sebastian Kirsch
* @author Phillip Webb
* @since 1.4.0
*/
@ConfigurationProperties
(
"endpoints.metrics.filter"
)
public
class
MetricFilterProperties
{
/**
* Submissions that should be made to the gauge.
*/
private
Set
<
MetricsFilterSubmission
>
gaugeSubmissions
;
/**
* Submissions that should be made to the counter.
*/
private
Set
<
MetricsFilterSubmission
>
counterSubmissions
;
public
MetricFilterProperties
()
{
this
.
gaugeSubmissions
=
new
HashSet
<
MetricsFilterSubmission
>(
EnumSet
.
of
(
MetricsFilterSubmission
.
MERGED
));
this
.
counterSubmissions
=
new
HashSet
<
MetricsFilterSubmission
>(
EnumSet
.
of
(
MetricsFilterSubmission
.
MERGED
));
}
public
Set
<
MetricsFilterSubmission
>
getGaugeSubmissions
()
{
return
this
.
gaugeSubmissions
;
}
public
void
setGaugeSubmissions
(
Set
<
MetricsFilterSubmission
>
gaugeSubmissions
)
{
this
.
gaugeSubmissions
=
gaugeSubmissions
;
}
public
Set
<
MetricsFilterSubmission
>
getCounterSubmissions
()
{
return
this
.
counterSubmissions
;
}
public
void
setCounterSubmissions
(
Set
<
MetricsFilterSubmission
>
counterSubmissions
)
{
this
.
counterSubmissions
=
counterSubmissions
;
}
boolean
shouldSubmitToGauge
(
MetricsFilterSubmission
submission
)
{
return
shouldSubmit
(
this
.
gaugeSubmissions
,
submission
);
}
boolean
shouldSubmitToCounter
(
MetricsFilterSubmission
submission
)
{
return
shouldSubmit
(
this
.
counterSubmissions
,
submission
);
}
private
boolean
shouldSubmit
(
Set
<
MetricsFilterSubmission
>
submissions
,
MetricsFilterSubmission
submission
)
{
return
submissions
!=
null
&&
submissions
.
contains
(
submission
);
}
}
spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/MetricsFilter.java
View file @
37fa3a3b
...
@@ -61,6 +61,8 @@ final class MetricsFilter extends OncePerRequestFilter {
...
@@ -61,6 +61,8 @@ final class MetricsFilter extends OncePerRequestFilter {
private
final
GaugeService
gaugeService
;
private
final
GaugeService
gaugeService
;
private
final
MetricFilterProperties
properties
;
private
static
final
Set
<
PatternReplacer
>
STATUS_REPLACERS
;
private
static
final
Set
<
PatternReplacer
>
STATUS_REPLACERS
;
static
{
static
{
...
@@ -82,9 +84,11 @@ final class MetricsFilter extends OncePerRequestFilter {
...
@@ -82,9 +84,11 @@ final class MetricsFilter extends OncePerRequestFilter {
KEY_REPLACERS
=
Collections
.
unmodifiableSet
(
replacements
);
KEY_REPLACERS
=
Collections
.
unmodifiableSet
(
replacements
);
}
}
MetricsFilter
(
CounterService
counterService
,
GaugeService
gaugeService
)
{
MetricsFilter
(
CounterService
counterService
,
GaugeService
gaugeService
,
MetricFilterProperties
properties
)
{
this
.
counterService
=
counterService
;
this
.
counterService
=
counterService
;
this
.
gaugeService
=
gaugeService
;
this
.
gaugeService
=
gaugeService
;
this
.
properties
=
properties
;
}
}
@Override
@Override
...
@@ -134,8 +138,9 @@ final class MetricsFilter extends OncePerRequestFilter {
...
@@ -134,8 +138,9 @@ final class MetricsFilter extends OncePerRequestFilter {
private
void
recordMetrics
(
HttpServletRequest
request
,
String
path
,
int
status
,
private
void
recordMetrics
(
HttpServletRequest
request
,
String
path
,
int
status
,
long
time
)
{
long
time
)
{
String
suffix
=
getFinalStatus
(
request
,
path
,
status
);
String
suffix
=
getFinalStatus
(
request
,
path
,
status
);
submitToGauge
(
getKey
(
"response"
+
suffix
),
time
);
submitMetrics
(
MetricsFilterSubmission
.
MERGED
,
request
,
status
,
time
,
suffix
);
incrementCounter
(
getKey
(
"status."
+
status
+
suffix
));
submitMetrics
(
MetricsFilterSubmission
.
PER_HTTP_METHOD
,
request
,
status
,
time
,
suffix
);
}
}
private
String
getFinalStatus
(
HttpServletRequest
request
,
String
path
,
int
status
)
{
private
String
getFinalStatus
(
HttpServletRequest
request
,
String
path
,
int
status
)
{
...
@@ -173,7 +178,20 @@ final class MetricsFilter extends OncePerRequestFilter {
...
@@ -173,7 +178,20 @@ final class MetricsFilter extends OncePerRequestFilter {
catch
(
Exception
ex
)
{
catch
(
Exception
ex
)
{
return
null
;
return
null
;
}
}
}
private
void
submitMetrics
(
MetricsFilterSubmission
submission
,
HttpServletRequest
request
,
int
status
,
long
time
,
String
suffix
)
{
String
prefix
=
""
;
if
(
submission
==
MetricsFilterSubmission
.
PER_HTTP_METHOD
)
{
prefix
=
request
.
getMethod
()
+
"."
;
}
if
(
this
.
properties
.
shouldSubmitToGauge
(
submission
))
{
submitToGauge
(
getKey
(
"response."
+
prefix
+
suffix
),
time
);
}
if
(
this
.
properties
.
shouldSubmitToCounter
(
submission
))
{
incrementCounter
(
getKey
(
"status."
+
prefix
+
status
+
suffix
));
}
}
}
private
String
getKey
(
String
string
)
{
private
String
getKey
(
String
string
)
{
...
...
spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/MetricsFilterSubmission.java
0 → 100644
View file @
37fa3a3b
/*
* Copyright 2012-2016 the original author or authors.
*
* 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
org
.
springframework
.
boot
.
actuate
.
autoconfigure
;
/**
* Submission types that can be made by the {@link MetricsFilter}.
*
* @author Phillip Webb
* @since 1.4.0
* @see MetricFilterProperties
*/
public
enum
MetricsFilterSubmission
{
/**
* Merge all HTTP methods into a single submission.
*/
MERGED
,
/**
* Group submissions by the HTTP method of the request.
*/
PER_HTTP_METHOD
}
spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/MetricFilterAutoConfigurationTests.java
View file @
37fa3a3b
...
@@ -64,6 +64,7 @@ import static org.mockito.Matchers.anyDouble;
...
@@ -64,6 +64,7 @@ import static org.mockito.Matchers.anyDouble;
import
static
org
.
mockito
.
Matchers
.
anyString
;
import
static
org
.
mockito
.
Matchers
.
anyString
;
import
static
org
.
mockito
.
Matchers
.
eq
;
import
static
org
.
mockito
.
Matchers
.
eq
;
import
static
org
.
mockito
.
Mockito
.
mock
;
import
static
org
.
mockito
.
Mockito
.
mock
;
import
static
org
.
mockito
.
Mockito
.
never
;
import
static
org
.
mockito
.
Mockito
.
times
;
import
static
org
.
mockito
.
Mockito
.
times
;
import
static
org
.
mockito
.
Mockito
.
verify
;
import
static
org
.
mockito
.
Mockito
.
verify
;
import
static
org
.
springframework
.
test
.
web
.
servlet
.
request
.
MockMvcRequestBuilders
.
asyncDispatch
;
import
static
org
.
springframework
.
test
.
web
.
servlet
.
request
.
MockMvcRequestBuilders
.
asyncDispatch
;
...
@@ -81,6 +82,15 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
...
@@ -81,6 +82,15 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
*/
*/
public
class
MetricFilterAutoConfigurationTests
{
public
class
MetricFilterAutoConfigurationTests
{
@Test
public
void
defaultMetricFilterAutoConfigurationProperties
()
{
MetricFilterProperties
properties
=
new
MetricFilterProperties
();
assertThat
(
properties
.
getGaugeSubmissions
())
.
containsExactly
(
MetricsFilterSubmission
.
MERGED
);
assertThat
(
properties
.
getCounterSubmissions
())
.
containsExactly
(
MetricsFilterSubmission
.
MERGED
);
}
@Test
@Test
public
void
recordsHttpInteractions
()
throws
Exception
{
public
void
recordsHttpInteractions
()
throws
Exception
{
AnnotationConfigApplicationContext
context
=
new
AnnotationConfigApplicationContext
(
AnnotationConfigApplicationContext
context
=
new
AnnotationConfigApplicationContext
(
...
@@ -295,6 +305,66 @@ public class MetricFilterAutoConfigurationTests {
...
@@ -295,6 +305,66 @@ public class MetricFilterAutoConfigurationTests {
context
.
close
();
context
.
close
();
}
}
@Test
public
void
additionallyRecordsMetricsWithHttpMethodNameIfConfigured
()
throws
Exception
{
AnnotationConfigApplicationContext
context
=
new
AnnotationConfigApplicationContext
();
context
.
register
(
Config
.
class
,
MetricFilterAutoConfiguration
.
class
);
EnvironmentTestUtils
.
addEnvironment
(
context
,
"endpoints.metrics.filter.gauge-submissions=merged,per-http-method"
,
"endpoints.metrics.filter.counter-submissions=merged,per-http-method"
);
context
.
refresh
();
Filter
filter
=
context
.
getBean
(
Filter
.
class
);
final
MockHttpServletRequest
request
=
new
MockHttpServletRequest
(
"PUT"
,
"/test/path"
);
final
MockHttpServletResponse
response
=
new
MockHttpServletResponse
();
FilterChain
chain
=
mock
(
FilterChain
.
class
);
willAnswer
(
new
Answer
<
Object
>()
{
@Override
public
Object
answer
(
InvocationOnMock
invocation
)
throws
Throwable
{
response
.
setStatus
(
200
);
return
null
;
}
}).
given
(
chain
).
doFilter
(
request
,
response
);
filter
.
doFilter
(
request
,
response
,
chain
);
verify
(
context
.
getBean
(
GaugeService
.
class
)).
submit
(
eq
(
"response.test.path"
),
anyDouble
());
verify
(
context
.
getBean
(
GaugeService
.
class
)).
submit
(
eq
(
"response.PUT.test.path"
),
anyDouble
());
verify
(
context
.
getBean
(
CounterService
.
class
))
.
increment
(
eq
(
"status.200.test.path"
));
verify
(
context
.
getBean
(
CounterService
.
class
))
.
increment
(
eq
(
"status.PUT.200.test.path"
));
context
.
close
();
}
@Test
public
void
doesNotRecordRolledUpMetricsIfConfigured
()
throws
Exception
{
AnnotationConfigApplicationContext
context
=
new
AnnotationConfigApplicationContext
();
context
.
register
(
Config
.
class
,
MetricFilterAutoConfiguration
.
class
);
EnvironmentTestUtils
.
addEnvironment
(
context
,
"endpoints.metrics.filter.gauge-submissions="
,
"endpoints.metrics.filter.counter-submissions="
);
context
.
refresh
();
Filter
filter
=
context
.
getBean
(
Filter
.
class
);
final
MockHttpServletRequest
request
=
new
MockHttpServletRequest
(
"PUT"
,
"/test/path"
);
final
MockHttpServletResponse
response
=
new
MockHttpServletResponse
();
FilterChain
chain
=
mock
(
FilterChain
.
class
);
willAnswer
(
new
Answer
<
Object
>()
{
@Override
public
Object
answer
(
InvocationOnMock
invocation
)
throws
Throwable
{
response
.
setStatus
(
200
);
return
null
;
}
}).
given
(
chain
).
doFilter
(
request
,
response
);
filter
.
doFilter
(
request
,
response
,
chain
);
verify
(
context
.
getBean
(
GaugeService
.
class
),
never
()).
submit
(
anyString
(),
anyDouble
());
verify
(
context
.
getBean
(
CounterService
.
class
),
never
()).
increment
(
anyString
());
context
.
close
();
}
@Configuration
@Configuration
public
static
class
Config
{
public
static
class
Config
{
...
...
spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc
View file @
37fa3a3b
...
@@ -896,6 +896,8 @@ content into your application; rather pick only the properties that you need.
...
@@ -896,6 +896,8 @@ content into your application; rather pick only the properties that you need.
endpoints.mappings.sensitive= # Mark if the endpoint exposes sensitive information.
endpoints.mappings.sensitive= # Mark if the endpoint exposes sensitive information.
endpoints.metrics.enabled= # Enable the endpoint.
endpoints.metrics.enabled= # Enable the endpoint.
endpoints.metrics.filter.enabled=true # Enable the metrics servlet filter.
endpoints.metrics.filter.enabled=true # Enable the metrics servlet filter.
endpoints.metrics.filter.gauge-submissions=merged # Http filter gauge submissions (merged, per-http-method)
endpoints.metrics.filter.counter-submissions=merged # Http filter counter submissions (merged, per-http-method)
endpoints.metrics.id= # Endpoint identifier.
endpoints.metrics.id= # Endpoint identifier.
endpoints.metrics.path= # Endpoint path.
endpoints.metrics.path= # Endpoint path.
endpoints.metrics.sensitive= # Mark if the endpoint exposes sensitive information.
endpoints.metrics.sensitive= # Mark if the endpoint exposes sensitive information.
...
...
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