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
01f7805c
Commit
01f7805c
authored
Oct 11, 2018
by
Phillip Webb
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch '2.0.x'
parents
ff35d141
b1399db9
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
82 additions
and
14 deletions
+82
-14
MetricsEndpoint.java
...springframework/boot/actuate/metrics/MetricsEndpoint.java
+17
-11
MetricsEndpointTests.java
...gframework/boot/actuate/metrics/MetricsEndpointTests.java
+36
-0
spring-boot-features.adoc
...ing-boot-docs/src/main/asciidoc/spring-boot-features.adoc
+19
-0
using-spring-boot.adoc
...spring-boot-docs/src/main/asciidoc/using-spring-boot.adoc
+10
-3
No files found.
spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/MetricsEndpoint.java
View file @
01f7805c
...
@@ -17,6 +17,7 @@
...
@@ -17,6 +17,7 @@
package
org
.
springframework
.
boot
.
actuate
.
metrics
;
package
org
.
springframework
.
boot
.
actuate
.
metrics
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Collection
;
import
java.util.Collections
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.HashMap
;
import
java.util.HashSet
;
import
java.util.HashSet
;
...
@@ -81,15 +82,15 @@ public class MetricsEndpoint {
...
@@ -81,15 +82,15 @@ public class MetricsEndpoint {
public
MetricResponse
metric
(
@Selector
String
requiredMetricName
,
public
MetricResponse
metric
(
@Selector
String
requiredMetricName
,
@Nullable
List
<
String
>
tag
)
{
@Nullable
List
<
String
>
tag
)
{
List
<
Tag
>
tags
=
parseTags
(
tag
);
List
<
Tag
>
tags
=
parseTags
(
tag
);
List
<
Meter
>
meters
=
new
ArrayList
<>();
Collection
<
Meter
>
meters
=
findFirstMatchingMeters
(
this
.
registry
,
collectMeters
(
meters
,
this
.
registry
,
requiredMetricName
,
tags
);
requiredMetricName
,
tags
);
if
(
meters
.
isEmpty
())
{
if
(
meters
.
isEmpty
())
{
return
null
;
return
null
;
}
}
Map
<
Statistic
,
Double
>
samples
=
getSamples
(
meters
);
Map
<
Statistic
,
Double
>
samples
=
getSamples
(
meters
);
Map
<
String
,
Set
<
String
>>
availableTags
=
getAvailableTags
(
meters
);
Map
<
String
,
Set
<
String
>>
availableTags
=
getAvailableTags
(
meters
);
tags
.
forEach
((
t
)
->
availableTags
.
remove
(
t
.
getKey
()));
tags
.
forEach
((
t
)
->
availableTags
.
remove
(
t
.
getKey
()));
Meter
.
Id
meterId
=
meters
.
get
(
0
).
getId
();
Meter
.
Id
meterId
=
meters
.
iterator
().
next
(
).
getId
();
return
new
MetricResponse
(
requiredMetricName
,
meterId
.
getDescription
(),
return
new
MetricResponse
(
requiredMetricName
,
meterId
.
getDescription
(),
meterId
.
getBaseUnit
(),
asList
(
samples
,
Sample:
:
new
),
meterId
.
getBaseUnit
(),
asList
(
samples
,
Sample:
:
new
),
asList
(
availableTags
,
AvailableTag:
:
new
));
asList
(
availableTags
,
AvailableTag:
:
new
));
...
@@ -112,18 +113,23 @@ public class MetricsEndpoint {
...
@@ -112,18 +113,23 @@ public class MetricsEndpoint {
return
Tag
.
of
(
parts
[
0
],
parts
[
1
]);
return
Tag
.
of
(
parts
[
0
],
parts
[
1
]);
}
}
private
void
collectMeters
(
List
<
Meter
>
meters
,
MeterRegistry
registry
,
String
name
,
private
Collection
<
Meter
>
findFirstMatchingMeters
(
MeterRegistry
registry
,
String
name
,
Iterable
<
Tag
>
tags
)
{
Iterable
<
Tag
>
tags
)
{
if
(
registry
instanceof
CompositeMeterRegistry
)
{
if
(
registry
instanceof
CompositeMeterRegistry
)
{
((
CompositeMeterRegistry
)
registry
).
getRegistries
()
return
findFirstMatchingMeters
((
CompositeMeterRegistry
)
registry
,
name
,
tags
);
.
forEach
((
member
)
->
collectMeters
(
meters
,
member
,
name
,
tags
));
}
else
{
meters
.
addAll
(
registry
.
find
(
name
).
tags
(
tags
).
meters
());
}
}
return
registry
.
find
(
name
).
tags
(
tags
).
meters
();
}
private
Collection
<
Meter
>
findFirstMatchingMeters
(
CompositeMeterRegistry
composite
,
String
name
,
Iterable
<
Tag
>
tags
)
{
return
composite
.
getRegistries
().
stream
()
.
map
((
registry
)
->
findFirstMatchingMeters
(
registry
,
name
,
tags
))
.
filter
((
matching
)
->
!
matching
.
isEmpty
()).
findFirst
()
.
orElse
(
Collections
.
emptyList
());
}
}
private
Map
<
Statistic
,
Double
>
getSamples
(
List
<
Meter
>
meters
)
{
private
Map
<
Statistic
,
Double
>
getSamples
(
Collection
<
Meter
>
meters
)
{
Map
<
Statistic
,
Double
>
samples
=
new
LinkedHashMap
<>();
Map
<
Statistic
,
Double
>
samples
=
new
LinkedHashMap
<>();
meters
.
forEach
((
meter
)
->
mergeMeasurements
(
samples
,
meter
));
meters
.
forEach
((
meter
)
->
mergeMeasurements
(
samples
,
meter
));
return
samples
;
return
samples
;
...
@@ -138,7 +144,7 @@ public class MetricsEndpoint {
...
@@ -138,7 +144,7 @@ public class MetricsEndpoint {
return
Statistic
.
MAX
.
equals
(
statistic
)
?
Double:
:
max
:
Double:
:
sum
;
return
Statistic
.
MAX
.
equals
(
statistic
)
?
Double:
:
max
:
Double:
:
sum
;
}
}
private
Map
<
String
,
Set
<
String
>>
getAvailableTags
(
List
<
Meter
>
meters
)
{
private
Map
<
String
,
Set
<
String
>>
getAvailableTags
(
Collection
<
Meter
>
meters
)
{
Map
<
String
,
Set
<
String
>>
availableTags
=
new
HashMap
<>();
Map
<
String
,
Set
<
String
>>
availableTags
=
new
HashMap
<>();
meters
.
forEach
((
meter
)
->
mergeAvailableTags
(
availableTags
,
meter
));
meters
.
forEach
((
meter
)
->
mergeAvailableTags
(
availableTags
,
meter
));
return
availableTags
;
return
availableTags
;
...
...
spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/MetricsEndpointTests.java
View file @
01f7805c
...
@@ -91,6 +91,42 @@ public class MetricsEndpointTests {
...
@@ -91,6 +91,42 @@ public class MetricsEndpointTests {
assertThat
(
getCount
(
response
)).
hasValue
(
4.0
);
assertThat
(
getCount
(
response
)).
hasValue
(
4.0
);
}
}
@Test
public
void
findFirstMatchingMetersFromNestedRegistries
()
{
CompositeMeterRegistry
composite
=
new
CompositeMeterRegistry
();
SimpleMeterRegistry
firstLevel0
=
new
SimpleMeterRegistry
();
CompositeMeterRegistry
firstLevel1
=
new
CompositeMeterRegistry
();
SimpleMeterRegistry
secondLevel
=
new
SimpleMeterRegistry
();
composite
.
add
(
firstLevel0
);
composite
.
add
(
firstLevel1
);
firstLevel1
.
add
(
secondLevel
);
secondLevel
.
counter
(
"cache"
,
"result"
,
"hit"
,
"host"
,
"1"
).
increment
(
2
);
secondLevel
.
counter
(
"cache"
,
"result"
,
"miss"
,
"host"
,
"1"
).
increment
(
2
);
secondLevel
.
counter
(
"cache"
,
"result"
,
"hit"
,
"host"
,
"2"
).
increment
(
2
);
MetricsEndpoint
endpoint
=
new
MetricsEndpoint
(
composite
);
MetricsEndpoint
.
MetricResponse
response
=
endpoint
.
metric
(
"cache"
,
Collections
.
emptyList
());
assertThat
(
response
.
getName
()).
isEqualTo
(
"cache"
);
assertThat
(
availableTagKeys
(
response
)).
containsExactly
(
"result"
,
"host"
);
assertThat
(
getCount
(
response
)).
hasValue
(
6.0
);
response
=
endpoint
.
metric
(
"cache"
,
Collections
.
singletonList
(
"result:hit"
));
assertThat
(
availableTagKeys
(
response
)).
containsExactly
(
"host"
);
assertThat
(
getCount
(
response
)).
hasValue
(
4.0
);
}
@Test
public
void
matchingMeterNotFoundInNestedRegistries
()
{
CompositeMeterRegistry
composite
=
new
CompositeMeterRegistry
();
CompositeMeterRegistry
firstLevel
=
new
CompositeMeterRegistry
();
SimpleMeterRegistry
secondLevel
=
new
SimpleMeterRegistry
();
composite
.
add
(
firstLevel
);
firstLevel
.
add
(
secondLevel
);
MetricsEndpoint
endpoint
=
new
MetricsEndpoint
(
composite
);
MetricsEndpoint
.
MetricResponse
response
=
endpoint
.
metric
(
"invalid.metric.name"
,
Collections
.
emptyList
());
assertThat
(
response
).
isNull
();
}
@Test
@Test
public
void
metricTagValuesAreDeduplicated
()
{
public
void
metricTagValuesAreDeduplicated
()
{
this
.
registry
.
counter
(
"cache"
,
"host"
,
"1"
,
"region"
,
"east"
,
"result"
,
"hit"
);
this
.
registry
.
counter
(
"cache"
,
"host"
,
"1"
,
"region"
,
"east"
,
"result"
,
"hit"
);
...
...
spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc
View file @
01f7805c
...
@@ -652,6 +652,21 @@ details.
...
@@ -652,6 +652,21 @@ details.
[[boot-features-encrypting-properties]]
=== Encrypting Properties
Spring Boot does not provide any built in support for encrypting property values, however,
it does provide the hook points necessary to modify values contained in the Spring
`Environment`. The `EnvironmentPostProcessor` interface allows you to manipulate the
`Environment` before the application starts. See <<howto-customize-the-environment-or-application-context>>
for details.
If you're looking for a secure way to store credentials and passwords, the
https://cloud.spring.io/spring-cloud-vault/[Spring Cloud Vault] project provides
support for storing externalized configuration in
https://www.vaultproject.io/[HashiCorp Vault].
[[boot-features-external-config-yaml]]
[[boot-features-external-config-yaml]]
=== Using YAML Instead of Properties
=== Using YAML Instead of Properties
http://yaml.org[YAML] is a superset of JSON and, as such, is a convenient format for
http://yaml.org[YAML] is a superset of JSON and, as such, is a convenient format for
...
@@ -6959,6 +6974,10 @@ that the driver exits after each test and that a new instance is injected. If yo
...
@@ -6959,6 +6974,10 @@ that the driver exits after each test and that a new instance is injected. If yo
not want this behavior, you can add `@Scope("singleton")` to your `WebDriver` `@Bean`
not want this behavior, you can add `@Scope("singleton")` to your `WebDriver` `@Bean`
definition.
definition.
WARNING: The `webDriver` scope created by Spring Boot will replace any user defined scope
of the same name. If you define your own `webDriver` scope you may find it stops working
when you use `@WebMvcTest`.
If you have Spring Security on the classpath, `@WebMvcTest` will also scan `WebSecurityConfigurer`
If you have Spring Security on the classpath, `@WebMvcTest` will also scan `WebSecurityConfigurer`
beans. Instead of disabling security completely for such tests, you can use Spring Security's test support.
beans. Instead of disabling security completely for such tests, you can use Spring Security's test support.
More details on how to use Spring Security's `MockMvc` support can be found in
More details on how to use Spring Security's `MockMvc` support can be found in
...
...
spring-boot-project/spring-boot-docs/src/main/asciidoc/using-spring-boot.adoc
View file @
01f7805c
...
@@ -749,16 +749,23 @@ listings for Maven and Gradle:
...
@@ -749,16 +749,23 @@ listings for Maven and Gradle:
.Gradle
.Gradle
[source,groovy,indent=0,subs="attributes"]
[source,groovy,indent=0,subs="attributes"]
----
----
configurations {
developmentOnly
runtimeClasspath {
extendsFrom developmentOnly
}
}
dependencies {
dependencies {
compile
("org.springframework.boot:spring-boot-devtools")
developmentOnly
("org.springframework.boot:spring-boot-devtools")
}
}
----
----
NOTE: Developer tools are automatically disabled when running a fully packaged
NOTE: Developer tools are automatically disabled when running a fully packaged
application. If your application is launched from `java -jar` or if it is started from a
application. If your application is launched from `java -jar` or if it is started from a
special classloader, then it is considered a "`production application`". Flagging the
special classloader, then it is considered a "`production application`". Flagging the
dependency as optional in Maven or using `compileOnly` in Gradle is a best practice that
dependency as optional in Maven or using a custom`developmentOnly` configuration in
prevents devtools from being transitively applied to other modules that use your project.
Gradle (as shown above) is a best practice that prevents devtools from being transitively
applied to other modules that use your project.
TIP: Repackaged archives do not contain devtools by default. If you want to use a
TIP: Repackaged archives do not contain devtools by default. If you want to use a
<<using-boot-devtools-remote,certain remote devtools feature>>, you need to disable the
<<using-boot-devtools-remote,certain remote devtools feature>>, you need to disable the
...
...
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