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
76748419
Commit
76748419
authored
Nov 24, 2017
by
Andy Wilkinson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Log condition evaluation delta upon DevTools restart
parent
480039f2
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
170 additions
and
17 deletions
+170
-17
ConditionEvaluationReport.java
...ot/autoconfigure/condition/ConditionEvaluationReport.java
+21
-0
ConditionEvaluationReportMessage.java
...toconfigure/logging/ConditionEvaluationReportMessage.java
+58
-17
ConditionEvaluationDeltaLoggingListener.java
...utoconfigure/ConditionEvaluationDeltaLoggingListener.java
+60
-0
DevToolsProperties.java
...ework/boot/devtools/autoconfigure/DevToolsProperties.java
+13
-0
LocalDevToolsAutoConfiguration.java
...evtools/autoconfigure/LocalDevToolsAutoConfiguration.java
+6
-0
using-spring-boot.adoc
...spring-boot-docs/src/main/asciidoc/using-spring-boot.adoc
+12
-0
No files found.
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionEvaluationReport.java
View file @
76748419
...
...
@@ -188,6 +188,27 @@ public final class ConditionEvaluationReport {
}
}
public
ConditionEvaluationReport
getDelta
(
ConditionEvaluationReport
previousReport
)
{
ConditionEvaluationReport
delta
=
new
ConditionEvaluationReport
();
for
(
Entry
<
String
,
ConditionAndOutcomes
>
entry
:
this
.
outcomes
.
entrySet
())
{
ConditionAndOutcomes
previous
=
previousReport
.
outcomes
.
get
(
entry
.
getKey
());
if
(
previous
==
null
||
previous
.
isFullMatch
()
!=
entry
.
getValue
().
isFullMatch
())
{
entry
.
getValue
()
.
forEach
((
conditionAndOutcome
)
->
delta
.
recordConditionEvaluation
(
entry
.
getKey
(),
conditionAndOutcome
.
getCondition
(),
conditionAndOutcome
.
getOutcome
()));
}
}
List
<
String
>
newExclusions
=
new
ArrayList
<>(
this
.
exclusions
);
newExclusions
.
removeAll
(
previousReport
.
getExclusions
());
delta
.
recordExclusions
(
newExclusions
);
List
<
String
>
newUnconditionalClasses
=
new
ArrayList
<>(
this
.
unconditionalClasses
);
newUnconditionalClasses
.
removeAll
(
previousReport
.
unconditionalClasses
);
delta
.
unconditionalClasses
.
addAll
(
newUnconditionalClasses
);
return
delta
;
}
/**
* Provides access to a number of {@link ConditionAndOutcome} items.
*/
...
...
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/logging/ConditionEvaluationReportMessage.java
View file @
76748419
...
...
@@ -22,6 +22,8 @@ import java.util.HashMap;
import
java.util.LinkedHashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Map.Entry
;
import
java.util.stream.Collectors
;
import
org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport
;
import
org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport.ConditionAndOutcome
;
...
...
@@ -33,6 +35,7 @@ import org.springframework.util.StringUtils;
* A condition evaluation report message that can logged or printed.
*
* @author Phillip Webb
* @author Andy Wilkinson
* @since 1.4.0
*/
public
class
ConditionEvaluationReportMessage
{
...
...
@@ -40,33 +43,69 @@ public class ConditionEvaluationReportMessage {
private
StringBuilder
message
;
public
ConditionEvaluationReportMessage
(
ConditionEvaluationReport
report
)
{
this
.
message
=
getLogMessage
(
report
);
this
(
report
,
"CONDITIONS EVALUATION REPORT"
);
}
private
StringBuilder
getLogMessage
(
ConditionEvaluationReport
report
)
{
public
ConditionEvaluationReportMessage
(
ConditionEvaluationReport
report
,
String
title
)
{
this
.
message
=
getLogMessage
(
report
,
title
);
}
private
StringBuilder
getLogMessage
(
ConditionEvaluationReport
report
,
String
title
)
{
StringBuilder
message
=
new
StringBuilder
();
message
.
append
(
String
.
format
(
"%n%n%n"
));
message
.
append
(
String
.
format
(
"=========================%n"
));
message
.
append
(
String
.
format
(
"CONDITIONS REPORT%n"
));
message
.
append
(
String
.
format
(
"=========================%n%n%n"
));
message
.
append
(
String
.
format
(
"Positive matches:%n"
));
message
.
append
(
String
.
format
(
"-----------------%n"
));
StringBuilder
separator
=
new
StringBuilder
();
for
(
int
i
=
0
;
i
<
title
.
length
();
i
++)
{
separator
.
append
(
"="
);
}
message
.
append
(
String
.
format
(
"%s%n"
,
separator
));
message
.
append
(
String
.
format
(
"%s%n"
,
title
));
message
.
append
(
String
.
format
(
"%s%n%n%n"
,
separator
));
Map
<
String
,
ConditionAndOutcomes
>
shortOutcomes
=
orderByName
(
report
.
getConditionAndOutcomesBySource
());
for
(
Map
.
Entry
<
String
,
ConditionAndOutcomes
>
entry
:
shortOutcomes
.
entrySet
())
{
if
(
entry
.
getValue
().
isFullMatch
())
{
addMatchLogMessage
(
message
,
entry
.
getKey
(),
entry
.
getValue
());
}
logPositiveMatches
(
message
,
shortOutcomes
);
logNegativeMatches
(
message
,
shortOutcomes
);
logExclusions
(
report
,
message
);
logUnconditionalClasses
(
report
,
message
);
message
.
append
(
String
.
format
(
"%n%n"
));
return
message
;
}
private
void
logPositiveMatches
(
StringBuilder
message
,
Map
<
String
,
ConditionAndOutcomes
>
shortOutcomes
)
{
message
.
append
(
String
.
format
(
"Positive matches:%n"
));
message
.
append
(
String
.
format
(
"-----------------%n"
));
List
<
Entry
<
String
,
ConditionAndOutcomes
>>
matched
=
shortOutcomes
.
entrySet
()
.
stream
().
filter
((
entry
)
->
entry
.
getValue
().
isFullMatch
())
.
collect
(
Collectors
.
toList
());
if
(
matched
.
isEmpty
())
{
message
.
append
(
String
.
format
(
"%n None%n"
));
}
else
{
matched
.
forEach
((
entry
)
->
addMatchLogMessage
(
message
,
entry
.
getKey
(),
entry
.
getValue
()));
}
message
.
append
(
String
.
format
(
"%n%n"
));
}
private
void
logNegativeMatches
(
StringBuilder
message
,
Map
<
String
,
ConditionAndOutcomes
>
shortOutcomes
)
{
message
.
append
(
String
.
format
(
"Negative matches:%n"
));
message
.
append
(
String
.
format
(
"-----------------%n"
));
for
(
Map
.
Entry
<
String
,
ConditionAndOutcomes
>
entry
:
shortOutcomes
.
entrySet
())
{
if
(!
entry
.
getValue
().
isFullMatch
())
{
addNonMatchLogMessage
(
message
,
entry
.
getKey
(),
entry
.
getValue
());
}
List
<
Entry
<
String
,
ConditionAndOutcomes
>>
nonMatched
=
shortOutcomes
.
entrySet
()
.
stream
().
filter
((
entry
)
->
!
entry
.
getValue
().
isFullMatch
())
.
collect
(
Collectors
.
toList
());
if
(
nonMatched
.
isEmpty
())
{
message
.
append
(
String
.
format
(
"%n None%n"
));
}
else
{
nonMatched
.
forEach
((
entry
)
->
addNonMatchLogMessage
(
message
,
entry
.
getKey
(),
entry
.
getValue
()));
}
message
.
append
(
String
.
format
(
"%n%n"
));
}
private
void
logExclusions
(
ConditionEvaluationReport
report
,
StringBuilder
message
)
{
message
.
append
(
String
.
format
(
"Exclusions:%n"
));
message
.
append
(
String
.
format
(
"-----------%n"
));
if
(
report
.
getExclusions
().
isEmpty
())
{
...
...
@@ -78,6 +117,10 @@ public class ConditionEvaluationReportMessage {
}
}
message
.
append
(
String
.
format
(
"%n%n"
));
}
private
void
logUnconditionalClasses
(
ConditionEvaluationReport
report
,
StringBuilder
message
)
{
message
.
append
(
String
.
format
(
"Unconditional classes:%n"
));
message
.
append
(
String
.
format
(
"----------------------%n"
));
if
(
report
.
getUnconditionalClasses
().
isEmpty
())
{
...
...
@@ -88,8 +131,6 @@ public class ConditionEvaluationReportMessage {
message
.
append
(
String
.
format
(
"%n %s%n"
,
unconditionalClass
));
}
}
message
.
append
(
String
.
format
(
"%n%n"
));
return
message
;
}
private
Map
<
String
,
ConditionAndOutcomes
>
orderByName
(
...
...
spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/ConditionEvaluationDeltaLoggingListener.java
0 → 100644
View file @
76748419
/*
* Copyright 2012-2017 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
.
devtools
.
autoconfigure
;
import
org.apache.commons.logging.Log
;
import
org.apache.commons.logging.LogFactory
;
import
org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport
;
import
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportMessage
;
import
org.springframework.boot.context.event.ApplicationReadyEvent
;
import
org.springframework.context.ApplicationListener
;
/**
* An {@link ApplicationListener} that logs the delta of condition evaluation across
* restarts.
*
* @author Andy Wilkinson
*/
class
ConditionEvaluationDeltaLoggingListener
implements
ApplicationListener
<
ApplicationReadyEvent
>
{
private
final
Log
logger
=
LogFactory
.
getLog
(
getClass
());
private
static
ConditionEvaluationReport
previousReport
;
@Override
public
void
onApplicationEvent
(
ApplicationReadyEvent
event
)
{
ConditionEvaluationReport
report
=
event
.
getApplicationContext
()
.
getBean
(
ConditionEvaluationReport
.
class
);
if
(
previousReport
!=
null
)
{
ConditionEvaluationReport
delta
=
report
.
getDelta
(
previousReport
);
if
(!
delta
.
getConditionAndOutcomesBySource
().
isEmpty
()
||
!
delta
.
getExclusions
().
isEmpty
()
||
!
delta
.
getUnconditionalClasses
().
isEmpty
())
{
this
.
logger
.
info
(
"Condition evaluation delta:"
+
new
ConditionEvaluationReportMessage
(
delta
,
"CONDITION EVALUATION DELTA"
));
}
else
{
this
.
logger
.
info
(
"Condition evaluation unchanged"
);
}
}
previousReport
=
report
;
}
}
spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/DevToolsProperties.java
View file @
76748419
...
...
@@ -100,6 +100,11 @@ public class DevToolsProperties {
*/
private
List
<
File
>
additionalPaths
=
new
ArrayList
<>();
/**
* Whether to log the condition evaluation delta upon restart.
*/
private
boolean
logConditionEvaluationDelta
=
true
;
public
boolean
isEnabled
()
{
return
this
.
enabled
;
}
...
...
@@ -168,6 +173,14 @@ public class DevToolsProperties {
this
.
additionalPaths
=
additionalPaths
;
}
public
boolean
isLogConditionEvaluationDelta
()
{
return
this
.
logConditionEvaluationDelta
;
}
public
void
setLogConditionEvaluationDelta
(
boolean
logConditionEvaluationDelta
)
{
this
.
logConditionEvaluationDelta
=
logConditionEvaluationDelta
;
}
}
/**
...
...
spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/LocalDevToolsAutoConfiguration.java
View file @
76748419
...
...
@@ -140,6 +140,12 @@ public class LocalDevToolsAutoConfiguration {
return
this
::
newFileSystemWatcher
;
}
@Bean
@ConditionalOnProperty
(
prefix
=
"spring.devtools.restart"
,
name
=
"log-condition-evaluation-delta"
,
matchIfMissing
=
true
)
public
ConditionEvaluationDeltaLoggingListener
conditionEvaluationDeltaLoggingListener
()
{
return
new
ConditionEvaluationDeltaLoggingListener
();
}
private
FileSystemWatcher
newFileSystemWatcher
()
{
Restart
restartProperties
=
this
.
properties
.
getRestart
();
FileSystemWatcher
watcher
=
new
FileSystemWatcher
(
true
,
...
...
spring-boot-project/spring-boot-docs/src/main/asciidoc/using-spring-boot.adoc
View file @
76748419
...
...
@@ -813,6 +813,18 @@ http://zeroturnaround.com/software/jrebel/[JRebel] from ZeroTurnaround. These wo
rewriting classes as they are loaded to make them more amenable to reloading.
****
[[using-boot-devtools-restart-logging-condition-delta]]
==== Logging changes in condition evaluation
By default, each time your application restarts, a report showing the condition evaluation
delta is logged. The report shows the changes to your application's auto-configuration as
you make changes such as adding or removing beans and setting configuration properties.
To disable the logging of the report, set the following property:
[indent=0]
----
spring.devtools.restart.log-condition-evaluation-delta=false
----
[[using-boot-devtools-restart-exclude]]
...
...
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