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
61b86ff2
Commit
61b86ff2
authored
Jul 30, 2019
by
Madhura Bhave
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Polish "Add support for configuring logging groups"
See gh-17515 Co-authored-by:
Phillip Webb
<
pwebb@pivotal.io
>
parent
b9047c22
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
442 additions
and
326 deletions
+442
-326
loggers.adoc
...or-autoconfigure/src/main/asciidoc/endpoints/loggers.adoc
+39
-0
LoggersEndpointAutoConfiguration.java
...toconfigure/logging/LoggersEndpointAutoConfiguration.java
+3
-3
LoggersEndpointDocumentationTests.java
.../web/documentation/LoggersEndpointDocumentationTests.java
+30
-29
LoggersEndpoint.java
...springframework/boot/actuate/logging/LoggersEndpoint.java
+23
-28
LoggersEndpointTests.java
...gframework/boot/actuate/logging/LoggersEndpointTests.java
+29
-35
LoggersEndpointWebIntegrationTests.java
...t/actuate/logging/LoggersEndpointWebIntegrationTests.java
+36
-59
LoggingApplicationListener.java
...work/boot/context/logging/LoggingApplicationListener.java
+86
-60
LoggerGroup.java
...in/java/org/springframework/boot/logging/LoggerGroup.java
+65
-0
LoggerGroups.java
...n/java/org/springframework/boot/logging/LoggerGroups.java
+63
-0
LoggingGroups.java
.../java/org/springframework/boot/logging/LoggingGroups.java
+0
-112
LoggingApplicationListenerTests.java
...boot/context/logging/LoggingApplicationListenerTests.java
+3
-0
LoggerGroupsTests.java
...a/org/springframework/boot/logging/LoggerGroupsTests.java
+65
-0
No files found.
spring-boot-project/spring-boot-actuator-autoconfigure/src/main/asciidoc/endpoints/loggers.adoc
View file @
61b86ff2
...
...
@@ -57,6 +57,21 @@ include::{snippets}loggers/single/response-fields.adoc[]
[[loggers-group]]
== Retrieving a Single Group
To retrieve a single group, make a `GET` request to `/actuator/loggers/{group.name}`,
as shown in the following curl-based example:
include::{snippets}loggers/group/curl-request.adoc[]
The preceding example retrieves information about the logger group named `test`. The
resulting response is similar to the following:
include::{snippets}loggers/group/http-response.adoc[]
[[loggers-setting-level]]
== Setting a Log Level
...
...
@@ -81,6 +96,30 @@ include::{snippets}loggers/set/request-fields.adoc[]
[[loggers-setting-level]]
== Setting a Log Level for a Group
To set the level of a logger, make a `POST` request to
`/actuator/loggers/{group.name}` with a JSON body that specifies the configured level
for the logger group, as shown in the following curl-based example:
include::{snippets}loggers/setGroup/curl-request.adoc[]
The preceding example sets the `configuredLevel` of the `test` logger group to `DEBUG`.
[[loggers-setting-level-request-structure]]
=== Request Structure
The request specifies the desired level of the logger group. The following table describes the
structure of the request:
[cols="3,1,3"]
include::{snippets}loggers/set/request-fields.adoc[]
[[loggers-clearing-level]]
== Clearing a Log Level
...
...
spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/logging/LoggersEndpointAutoConfiguration.java
View file @
61b86ff2
...
...
@@ -25,7 +25,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnBean
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
;
import
org.springframework.boot.autoconfigure.condition.SpringBootCondition
;
import
org.springframework.boot.logging.Logg
ing
Groups
;
import
org.springframework.boot.logging.Logg
er
Groups
;
import
org.springframework.boot.logging.LoggingSystem
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.ConditionContext
;
...
...
@@ -48,8 +48,8 @@ public class LoggersEndpointAutoConfiguration {
@Conditional
(
OnEnabledLoggingSystemCondition
.
class
)
@ConditionalOnMissingBean
public
LoggersEndpoint
loggersEndpoint
(
LoggingSystem
loggingSystem
,
ObjectProvider
<
Logg
ingGroups
>
loggingGroupsObjectProvider
)
{
return
new
LoggersEndpoint
(
loggingSystem
,
loggingGroupsObjectProvider
.
getIfAvailable
(
));
ObjectProvider
<
Logg
erGroups
>
springBootLoggerGroups
)
{
return
new
LoggersEndpoint
(
loggingSystem
,
springBootLoggerGroups
.
getIfAvailable
(
LoggerGroups:
:
new
));
}
static
class
OnEnabledLoggingSystemCondition
extends
SpringBootCondition
{
...
...
spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/LoggersEndpointDocumentationTests.java
View file @
61b86ff2
...
...
@@ -20,14 +20,15 @@ import java.util.Arrays;
import
java.util.Collections
;
import
java.util.EnumSet
;
import
java.util.List
;
import
java.util.Map
;
import
org.junit.jupiter.api.Test
;
import
org.springframework.beans.factory.
ObjectProvider
;
import
org.springframework.beans.factory.
annotation.Autowired
;
import
org.springframework.boot.actuate.logging.LoggersEndpoint
;
import
org.springframework.boot.logging.LogLevel
;
import
org.springframework.boot.logging.LoggerConfiguration
;
import
org.springframework.boot.logging.Logg
ing
Groups
;
import
org.springframework.boot.logging.Logg
er
Groups
;
import
org.springframework.boot.logging.LoggingSystem
;
import
org.springframework.boot.test.mock.mockito.MockBean
;
import
org.springframework.context.annotation.Bean
;
...
...
@@ -57,18 +58,20 @@ class LoggersEndpointDocumentationTests extends MockMvcEndpointDocumentationTest
fieldWithPath
(
"configuredLevel"
).
description
(
"Configured level of the logger, if any."
).
optional
(),
fieldWithPath
(
"effectiveLevel"
).
description
(
"Effective level of the logger."
));
private
static
final
List
<
FieldDescriptor
>
groupLevelFields
=
Arrays
.
asList
(
fieldWithPath
(
"configuredLevel"
).
description
(
"Configured level of the logger group"
),
fieldWithPath
(
"members"
).
description
(
"Loggers that are part of this group"
).
optional
());
private
static
final
List
<
FieldDescriptor
>
groupLevelFields
;
@MockBean
private
LoggingSystem
loggingSystem
;
static
{
groupLevelFields
=
Arrays
.
asList
(
fieldWithPath
(
"configuredLevel"
).
description
(
"Configured level of the logger group"
)
.
type
(
LogLevel
.
class
).
optional
(),
fieldWithPath
(
"members"
).
description
(
"Loggers that are part of this group"
).
optional
());
}
@MockBean
private
ObjectProvider
<
LoggingGroups
>
loggingGroupsObjectProvider
;
private
LoggingSystem
loggingSystem
;
@
MockBean
LoggingGroups
logging
Groups
;
@
Autowired
private
LoggerGroups
logger
Groups
;
@Test
void
allLoggers
()
throws
Exception
{
...
...
@@ -76,10 +79,6 @@ class LoggersEndpointDocumentationTests extends MockMvcEndpointDocumentationTest
given
(
this
.
loggingSystem
.
getLoggerConfigurations
())
.
willReturn
(
Arrays
.
asList
(
new
LoggerConfiguration
(
"ROOT"
,
LogLevel
.
INFO
,
LogLevel
.
INFO
),
new
LoggerConfiguration
(
"com.example"
,
LogLevel
.
DEBUG
,
LogLevel
.
DEBUG
)));
given
(
this
.
loggingGroupsObjectProvider
.
getIfAvailable
()).
willReturn
(
this
.
loggingGroups
);
given
(
this
.
loggingGroups
.
getLoggerGroupNames
()).
willReturn
(
Collections
.
singleton
(
"test"
));
given
(
this
.
loggingGroups
.
getLoggerGroup
(
"test"
)).
willReturn
(
Arrays
.
asList
(
"test.member"
));
given
(
this
.
loggingGroups
.
getLoggerGroupConfiguredLevel
(
"test"
)).
willReturn
(
LogLevel
.
INFO
);
this
.
mockMvc
.
perform
(
get
(
"/actuator/loggers"
)).
andExpect
(
status
().
isOk
())
.
andDo
(
MockMvcRestDocumentation
.
document
(
"loggers/all"
,
responseFields
(
fieldWithPath
(
"levels"
).
description
(
"Levels support by the logging system."
),
...
...
@@ -91,7 +90,6 @@ class LoggersEndpointDocumentationTests extends MockMvcEndpointDocumentationTest
@Test
void
logger
()
throws
Exception
{
given
(
this
.
loggingGroupsObjectProvider
.
getIfAvailable
()).
willReturn
(
this
.
loggingGroups
);
given
(
this
.
loggingSystem
.
getLoggerConfiguration
(
"com.example"
))
.
willReturn
(
new
LoggerConfiguration
(
"com.example"
,
LogLevel
.
INFO
,
LogLevel
.
INFO
));
this
.
mockMvc
.
perform
(
get
(
"/actuator/loggers/com.example"
)).
andExpect
(
status
().
isOk
())
...
...
@@ -100,17 +98,12 @@ class LoggersEndpointDocumentationTests extends MockMvcEndpointDocumentationTest
@Test
void
loggerGroups
()
throws
Exception
{
given
(
this
.
loggingGroupsObjectProvider
.
getIfAvailable
()).
willReturn
(
this
.
loggingGroups
);
given
(
this
.
loggingGroups
.
isGroup
(
"com.example"
)).
willReturn
(
true
);
given
(
this
.
loggingGroups
.
getLoggerGroup
(
"com.example"
)).
willReturn
(
Arrays
.
asList
(
"com.member"
,
"com.member2"
));
given
(
this
.
loggingGroups
.
getLoggerGroupConfiguredLevel
(
"com.example"
)).
willReturn
(
LogLevel
.
INFO
);
this
.
mockMvc
.
perform
(
get
(
"/actuator/loggers/com.example"
)).
andExpect
(
status
().
isOk
())
this
.
mockMvc
.
perform
(
get
(
"/actuator/loggers/test"
)).
andExpect
(
status
().
isOk
())
.
andDo
(
MockMvcRestDocumentation
.
document
(
"loggers/group"
,
responseFields
(
groupLevelFields
)));
}
@Test
void
setLogLevel
()
throws
Exception
{
given
(
this
.
loggingGroupsObjectProvider
.
getIfAvailable
()).
willReturn
(
this
.
loggingGroups
);
this
.
mockMvc
.
perform
(
post
(
"/actuator/loggers/com.example"
).
content
(
"{\"configuredLevel\":\"debug\"}"
)
.
contentType
(
MediaType
.
APPLICATION_JSON
))
...
...
@@ -122,22 +115,26 @@ class LoggersEndpointDocumentationTests extends MockMvcEndpointDocumentationTest
@Test
void
setLogLevelOfLoggerGroup
()
throws
Exception
{
given
(
this
.
loggingGroupsObjectProvider
.
getIfAvailable
()).
willReturn
(
this
.
loggingGroups
);
given
(
this
.
loggingGroups
.
isGroup
(
"com.example"
)).
willReturn
(
true
);
this
.
mockMvc
.
perform
(
post
(
"/actuator/loggers/
com.example
"
)
.
perform
(
post
(
"/actuator/loggers/
test
"
)
.
content
(
"{\"configuredLevel\":\"debug\"}"
).
contentType
(
MediaType
.
APPLICATION_JSON
))
.
andExpect
(
status
().
isNoContent
()).
andDo
(
MockMvcRestDocumentation
.
document
(
"loggers/setGroup"
,
requestFields
(
fieldWithPath
(
"configuredLevel"
).
description
(
"Level for the logger group. May be omitted to clear the level of the loggers."
)
.
optional
())));
verify
(
this
.
loggingGroups
).
setLoggerGroupLevel
(
"com.example"
,
LogLevel
.
DEBUG
);
verify
(
this
.
loggingSystem
).
setLogLevel
(
"test.member1"
,
LogLevel
.
DEBUG
);
verify
(
this
.
loggingSystem
).
setLogLevel
(
"test.member2"
,
LogLevel
.
DEBUG
);
resetLogger
();
}
private
void
resetLogger
()
{
this
.
loggerGroups
.
get
(
"test"
).
configureLogLevel
(
null
,
(
a
,
b
)
->
{
});
}
@Test
void
clearLogLevel
()
throws
Exception
{
given
(
this
.
loggingGroupsObjectProvider
.
getIfAvailable
()).
willReturn
(
this
.
loggingGroups
);
this
.
mockMvc
.
perform
(
post
(
"/actuator/loggers/com.example"
).
content
(
"{}"
).
contentType
(
MediaType
.
APPLICATION_JSON
))
.
andExpect
(
status
().
isNoContent
()).
andDo
(
MockMvcRestDocumentation
.
document
(
"loggers/clear"
));
...
...
@@ -149,9 +146,13 @@ class LoggersEndpointDocumentationTests extends MockMvcEndpointDocumentationTest
static
class
TestConfiguration
{
@Bean
LoggersEndpoint
endpoint
(
LoggingSystem
loggingSystem
,
ObjectProvider
<
LoggingGroups
>
loggingGroupsObjectProvider
)
{
return
new
LoggersEndpoint
(
loggingSystem
,
loggingGroupsObjectProvider
.
getIfAvailable
());
LoggersEndpoint
endpoint
(
LoggingSystem
loggingSystem
,
LoggerGroups
groups
)
{
groups
.
putAll
(
getLoggerGroups
());
return
new
LoggersEndpoint
(
loggingSystem
,
groups
);
}
private
Map
<
String
,
List
<
String
>>
getLoggerGroups
()
{
return
Collections
.
singletonMap
(
"test"
,
Arrays
.
asList
(
"test.member1"
,
"test.member2"
));
}
}
...
...
spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/logging/LoggersEndpoint.java
View file @
61b86ff2
...
...
@@ -31,7 +31,8 @@ import org.springframework.boot.actuate.endpoint.annotation.Selector;
import
org.springframework.boot.actuate.endpoint.annotation.WriteOperation
;
import
org.springframework.boot.logging.LogLevel
;
import
org.springframework.boot.logging.LoggerConfiguration
;
import
org.springframework.boot.logging.LoggingGroups
;
import
org.springframework.boot.logging.LoggerGroup
;
import
org.springframework.boot.logging.LoggerGroups
;
import
org.springframework.boot.logging.LoggingSystem
;
import
org.springframework.lang.Nullable
;
import
org.springframework.util.Assert
;
...
...
@@ -49,17 +50,18 @@ public class LoggersEndpoint {
private
final
LoggingSystem
loggingSystem
;
private
final
Logg
ingGroups
logging
Groups
;
private
final
Logg
erGroups
logger
Groups
;
/**
* Create a new {@link LoggersEndpoint} instance.
* @param loggingSystem the logging system to expose
* @param logg
ingGroups the logging group to expose if it exists
* @param logg
erGroups the logger group to expose
*/
public
LoggersEndpoint
(
LoggingSystem
loggingSystem
,
Logg
ingGroups
logging
Groups
)
{
public
LoggersEndpoint
(
LoggingSystem
loggingSystem
,
Logg
erGroups
logger
Groups
)
{
Assert
.
notNull
(
loggingSystem
,
"LoggingSystem must not be null"
);
Assert
.
notNull
(
loggerGroups
,
"LoggerGroups must not be null"
);
this
.
loggingSystem
=
loggingSystem
;
this
.
logg
ingGroups
=
logging
Groups
;
this
.
logg
erGroups
=
logger
Groups
;
}
@ReadOperation
...
...
@@ -71,20 +73,23 @@ public class LoggersEndpoint {
Map
<
String
,
Object
>
result
=
new
LinkedHashMap
<>();
result
.
put
(
"levels"
,
getLevels
());
result
.
put
(
"loggers"
,
getLoggers
(
configurations
));
if
(
this
.
loggingGroups
!=
null
&&
this
.
loggingGroups
.
getLoggerGroupNames
()
!=
null
)
{
Set
<
String
>
groups
=
this
.
loggingGroups
.
getLoggerGroupNames
();
result
.
put
(
"groups"
,
getLoggerGroups
(
groups
));
}
result
.
put
(
"groups"
,
getGroups
());
return
result
;
}
private
Map
<
String
,
LoggerLevels
>
getGroups
()
{
Map
<
String
,
LoggerLevels
>
groups
=
new
LinkedHashMap
<>();
this
.
loggerGroups
.
forEach
((
group
)
->
groups
.
put
(
group
.
getName
(),
new
GroupLoggerLevels
(
group
.
getConfiguredLevel
(),
group
.
getMembers
())));
return
groups
;
}
@ReadOperation
public
LoggerLevels
loggerLevels
(
@Selector
String
name
)
{
Assert
.
notNull
(
name
,
"Name must not be null"
);
if
(
this
.
loggingGroups
!=
null
&&
this
.
loggingGroups
.
isGroup
(
name
))
{
List
<
String
>
members
=
this
.
loggingGroups
.
getLoggerGroup
(
name
);
LogLevel
groupConfiguredLevel
=
this
.
loggingGroups
.
getLoggerGroupConfiguredLevel
(
name
);
return
new
GroupLoggerLevels
(
groupConfiguredLevel
,
members
);
LoggerGroup
group
=
this
.
loggerGroups
.
get
(
name
);
if
(
group
!=
null
)
{
return
new
GroupLoggerLevels
(
group
.
getConfiguredLevel
(),
group
.
getMembers
());
}
LoggerConfiguration
configuration
=
this
.
loggingSystem
.
getLoggerConfiguration
(
name
);
return
(
configuration
!=
null
)
?
new
SingleLoggerLevels
(
configuration
)
:
null
;
...
...
@@ -93,8 +98,9 @@ public class LoggersEndpoint {
@WriteOperation
public
void
configureLogLevel
(
@Selector
String
name
,
@Nullable
LogLevel
configuredLevel
)
{
Assert
.
notNull
(
name
,
"Name must not be empty"
);
if
(
this
.
loggingGroups
!=
null
&&
this
.
loggingGroups
.
isGroup
(
name
))
{
this
.
loggingGroups
.
setLoggerGroupLevel
(
name
,
configuredLevel
);
LoggerGroup
group
=
this
.
loggerGroups
.
get
(
name
);
if
(
group
!=
null
&&
group
.
hasMembers
())
{
group
.
configureLogLevel
(
configuredLevel
,
this
.
loggingSystem
::
setLogLevel
);
return
;
}
this
.
loggingSystem
.
setLogLevel
(
name
,
configuredLevel
);
...
...
@@ -113,16 +119,6 @@ public class LoggersEndpoint {
return
loggers
;
}
private
Map
<
String
,
LoggerLevels
>
getLoggerGroups
(
Set
<
String
>
groups
)
{
Map
<
String
,
LoggerLevels
>
loggerGroups
=
new
LinkedHashMap
<>(
groups
.
size
());
for
(
String
name
:
groups
)
{
List
<
String
>
members
=
this
.
loggingGroups
.
getLoggerGroup
(
name
);
LogLevel
groupConfiguredLevel
=
this
.
loggingGroups
.
getLoggerGroupConfiguredLevel
(
name
);
loggerGroups
.
put
(
name
,
new
GroupLoggerLevels
(
groupConfiguredLevel
,
members
));
}
return
loggerGroups
;
}
/**
* Levels configured for a given logger exposed in a JSON friendly way.
*/
...
...
@@ -134,13 +130,12 @@ public class LoggersEndpoint {
this
.
configuredLevel
=
getName
(
configuredLevel
);
}
pr
ivate
String
getName
(
LogLevel
level
)
{
pr
otected
final
String
getName
(
LogLevel
level
)
{
return
(
level
!=
null
)
?
level
.
name
()
:
null
;
}
public
String
getConfiguredLevel
()
{
return
this
.
configuredLevel
;
}
}
...
...
@@ -166,7 +161,7 @@ public class LoggersEndpoint {
public
SingleLoggerLevels
(
LoggerConfiguration
configuration
)
{
super
(
configuration
.
getConfiguredLevel
());
this
.
effectiveLevel
=
super
.
getName
(
configuration
.
getEffectiveLevel
());
this
.
effectiveLevel
=
getName
(
configuration
.
getEffectiveLevel
());
}
public
String
getEffectiveLevel
()
{
...
...
spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/logging/LoggersEndpointTests.java
View file @
61b86ff2
...
...
@@ -18,9 +18,11 @@ package org.springframework.boot.actuate.logging;
import
java.util.Collections
;
import
java.util.EnumSet
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
import
org.junit.jupiter.api.BeforeEach
;
import
org.junit.jupiter.api.Test
;
import
org.springframework.boot.actuate.logging.LoggersEndpoint.GroupLoggerLevels
;
...
...
@@ -28,7 +30,7 @@ import org.springframework.boot.actuate.logging.LoggersEndpoint.LoggerLevels;
import
org.springframework.boot.actuate.logging.LoggersEndpoint.SingleLoggerLevels
;
import
org.springframework.boot.logging.LogLevel
;
import
org.springframework.boot.logging.LoggerConfiguration
;
import
org.springframework.boot.logging.Logg
ing
Groups
;
import
org.springframework.boot.logging.Logg
er
Groups
;
import
org.springframework.boot.logging.LoggingSystem
;
import
static
org
.
assertj
.
core
.
api
.
Assertions
.
assertThat
;
...
...
@@ -42,12 +44,21 @@ import static org.mockito.Mockito.verify;
* @author Ben Hale
* @author Andy Wilkinson
* @author HaiTao Zhang
* @author Madhura Bhave
*/
class
LoggersEndpointTests
{
private
final
LoggingSystem
loggingSystem
=
mock
(
LoggingSystem
.
class
);
private
final
LoggingGroups
loggingGroups
=
mock
(
LoggingGroups
.
class
);
private
LoggerGroups
loggerGroups
;
@BeforeEach
void
setup
()
{
Map
<
String
,
List
<
String
>>
groups
=
Collections
.
singletonMap
(
"test"
,
Collections
.
singletonList
(
"test.member"
));
this
.
loggerGroups
=
new
LoggerGroups
(
groups
);
this
.
loggerGroups
.
get
(
"test"
).
configureLogLevel
(
LogLevel
.
DEBUG
,
(
a
,
b
)
->
{
});
}
@Test
@SuppressWarnings
(
"unchecked"
)
...
...
@@ -55,8 +66,7 @@ class LoggersEndpointTests {
given
(
this
.
loggingSystem
.
getLoggerConfigurations
())
.
willReturn
(
Collections
.
singletonList
(
new
LoggerConfiguration
(
"ROOT"
,
null
,
LogLevel
.
DEBUG
)));
given
(
this
.
loggingSystem
.
getSupportedLogLevels
()).
willReturn
(
EnumSet
.
allOf
(
LogLevel
.
class
));
given
(
this
.
loggingGroups
.
getLoggerGroupNames
()).
willReturn
(
null
);
Map
<
String
,
Object
>
result
=
new
LoggersEndpoint
(
this
.
loggingSystem
,
this
.
loggingGroups
).
loggers
();
Map
<
String
,
Object
>
result
=
new
LoggersEndpoint
(
this
.
loggingSystem
,
new
LoggerGroups
()).
loggers
();
Map
<
String
,
LoggerLevels
>
loggers
=
(
Map
<
String
,
LoggerLevels
>)
result
.
get
(
"loggers"
);
Set
<
LogLevel
>
levels
=
(
Set
<
LogLevel
>)
result
.
get
(
"levels"
);
SingleLoggerLevels
rootLevels
=
(
SingleLoggerLevels
)
loggers
.
get
(
"ROOT"
);
...
...
@@ -64,7 +74,8 @@ class LoggersEndpointTests {
assertThat
(
rootLevels
.
getEffectiveLevel
()).
isEqualTo
(
"DEBUG"
);
assertThat
(
levels
).
containsExactly
(
LogLevel
.
OFF
,
LogLevel
.
FATAL
,
LogLevel
.
ERROR
,
LogLevel
.
WARN
,
LogLevel
.
INFO
,
LogLevel
.
DEBUG
,
LogLevel
.
TRACE
);
assertThat
(
result
.
get
(
"groups"
)).
isNull
();
Map
<
String
,
LoggerGroups
>
groups
=
(
Map
<
String
,
LoggerGroups
>)
result
.
get
(
"groups"
);
assertThat
(
groups
).
isEmpty
();
}
@Test
...
...
@@ -73,12 +84,9 @@ class LoggersEndpointTests {
given
(
this
.
loggingSystem
.
getLoggerConfigurations
())
.
willReturn
(
Collections
.
singletonList
(
new
LoggerConfiguration
(
"ROOT"
,
null
,
LogLevel
.
DEBUG
)));
given
(
this
.
loggingSystem
.
getSupportedLogLevels
()).
willReturn
(
EnumSet
.
allOf
(
LogLevel
.
class
));
given
(
this
.
loggingGroups
.
getLoggerGroup
(
"test"
)).
willReturn
(
Collections
.
singletonList
(
"test.member"
));
given
(
this
.
loggingGroups
.
getLoggerGroupNames
()).
willReturn
(
Collections
.
singleton
(
"test"
));
given
(
this
.
loggingGroups
.
getLoggerGroupConfiguredLevel
(
"test"
)).
willReturn
(
LogLevel
.
DEBUG
);
Map
<
String
,
Object
>
result
=
new
LoggersEndpoint
(
this
.
loggingSystem
,
this
.
loggingGroups
).
loggers
();
Map
<
String
,
LoggerLevels
>
loggerGroups
=
(
Map
<
String
,
LoggerLevels
>)
result
.
get
(
"groups"
);
GroupLoggerLevels
testLoggerLevel
=
(
GroupLoggerLevels
)
loggerGroups
.
get
(
"test"
);
Map
<
String
,
Object
>
result
=
new
LoggersEndpoint
(
this
.
loggingSystem
,
this
.
loggerGroups
).
loggers
();
Map
<
String
,
GroupLoggerLevels
>
loggerGroups
=
(
Map
<
String
,
GroupLoggerLevels
>)
result
.
get
(
"groups"
);
GroupLoggerLevels
groupLevel
=
loggerGroups
.
get
(
"test"
);
Map
<
String
,
LoggerLevels
>
loggers
=
(
Map
<
String
,
LoggerLevels
>)
result
.
get
(
"loggers"
);
Set
<
LogLevel
>
levels
=
(
Set
<
LogLevel
>)
result
.
get
(
"levels"
);
SingleLoggerLevels
rootLevels
=
(
SingleLoggerLevels
)
loggers
.
get
(
"ROOT"
);
...
...
@@ -87,17 +95,15 @@ class LoggersEndpointTests {
assertThat
(
levels
).
containsExactly
(
LogLevel
.
OFF
,
LogLevel
.
FATAL
,
LogLevel
.
ERROR
,
LogLevel
.
WARN
,
LogLevel
.
INFO
,
LogLevel
.
DEBUG
,
LogLevel
.
TRACE
);
assertThat
(
loggerGroups
).
isNotNull
();
assertThat
(
testLoggerLevel
).
isNotNull
();
assertThat
(
testLoggerLevel
.
getConfiguredLevel
()).
isEqualTo
(
"DEBUG"
);
assertThat
(
testLoggerLevel
.
getMembers
()).
isEqualTo
(
Collections
.
singletonList
(
"test.member"
));
assertThat
(
groupLevel
.
getConfiguredLevel
()).
isEqualTo
(
"DEBUG"
);
assertThat
(
groupLevel
.
getMembers
()).
containsExactly
(
"test.member"
);
}
@Test
void
loggerLevelsWhenNameSpecifiedShouldReturnLevels
()
{
given
(
this
.
loggingGroups
.
isGroup
(
"ROOT"
)).
willReturn
(
false
);
given
(
this
.
loggingSystem
.
getLoggerConfiguration
(
"ROOT"
))
.
willReturn
(
new
LoggerConfiguration
(
"ROOT"
,
null
,
LogLevel
.
DEBUG
));
SingleLoggerLevels
levels
=
(
SingleLoggerLevels
)
new
LoggersEndpoint
(
this
.
loggingSystem
,
this
.
logg
ing
Groups
)
SingleLoggerLevels
levels
=
(
SingleLoggerLevels
)
new
LoggersEndpoint
(
this
.
loggingSystem
,
this
.
logg
er
Groups
)
.
loggerLevels
(
"ROOT"
);
assertThat
(
levels
.
getConfiguredLevel
()).
isNull
();
assertThat
(
levels
.
getEffectiveLevel
()).
isEqualTo
(
"DEBUG"
);
...
...
@@ -105,10 +111,7 @@ class LoggersEndpointTests {
@Test
void
groupNameSpecifiedShouldReturnConfiguredLevelAndMembers
()
{
given
(
this
.
loggingGroups
.
isGroup
(
"test"
)).
willReturn
(
true
);
given
(
this
.
loggingGroups
.
getLoggerGroup
(
"test"
)).
willReturn
(
Collections
.
singletonList
(
"test.member"
));
given
(
this
.
loggingGroups
.
getLoggerGroupConfiguredLevel
(
"test"
)).
willReturn
(
LogLevel
.
DEBUG
);
GroupLoggerLevels
levels
=
(
GroupLoggerLevels
)
new
LoggersEndpoint
(
this
.
loggingSystem
,
this
.
loggingGroups
)
GroupLoggerLevels
levels
=
(
GroupLoggerLevels
)
new
LoggersEndpoint
(
this
.
loggingSystem
,
this
.
loggerGroups
)
.
loggerLevels
(
"test"
);
assertThat
(
levels
.
getConfiguredLevel
()).
isEqualTo
(
"DEBUG"
);
assertThat
(
levels
.
getMembers
()).
isEqualTo
(
Collections
.
singletonList
(
"test.member"
));
...
...
@@ -116,35 +119,26 @@ class LoggersEndpointTests {
@Test
void
configureLogLevelShouldSetLevelOnLoggingSystem
()
{
given
(
this
.
loggingGroups
.
getLoggerGroup
(
"ROOT"
)).
willReturn
(
null
);
new
LoggersEndpoint
(
this
.
loggingSystem
,
this
.
loggingGroups
).
configureLogLevel
(
"ROOT"
,
LogLevel
.
DEBUG
);
new
LoggersEndpoint
(
this
.
loggingSystem
,
this
.
loggerGroups
).
configureLogLevel
(
"ROOT"
,
LogLevel
.
DEBUG
);
verify
(
this
.
loggingSystem
).
setLogLevel
(
"ROOT"
,
LogLevel
.
DEBUG
);
}
@Test
void
configureLogLevelWithNullSetsLevelOnLoggingSystemToNull
()
{
given
(
this
.
loggingGroups
.
getLoggerGroup
(
"ROOT"
)).
willReturn
(
null
);
new
LoggersEndpoint
(
this
.
loggingSystem
,
this
.
loggingGroups
).
configureLogLevel
(
"ROOT"
,
null
);
new
LoggersEndpoint
(
this
.
loggingSystem
,
this
.
loggerGroups
).
configureLogLevel
(
"ROOT"
,
null
);
verify
(
this
.
loggingSystem
).
setLogLevel
(
"ROOT"
,
null
);
}
@Test
void
configureLogLevelInLoggerGroupShouldSetLevelOnLoggingSystem
()
{
given
(
this
.
loggingGroups
.
isGroup
(
"test"
)).
willReturn
(
true
);
given
(
this
.
loggingGroups
.
getLoggerGroup
(
"test"
)).
willReturn
(
Collections
.
singletonList
(
"test.member"
));
new
LoggersEndpoint
(
this
.
loggingSystem
,
this
.
loggingGroups
).
configureLogLevel
(
"test"
,
LogLevel
.
DEBUG
);
verify
(
this
.
loggingGroups
).
setLoggerGroupLevel
(
"test"
,
LogLevel
.
DEBUG
);
new
LoggersEndpoint
(
this
.
loggingSystem
,
this
.
loggerGroups
).
configureLogLevel
(
"test"
,
LogLevel
.
DEBUG
);
verify
(
this
.
loggingSystem
).
setLogLevel
(
"test.member"
,
LogLevel
.
DEBUG
);
}
@Test
void
configureLogLevelWithNullInLoggerGroupShouldSetLevelOnLoggingSystem
()
{
given
(
this
.
loggingGroups
.
isGroup
(
"test"
)).
willReturn
(
true
);
given
(
this
.
loggingGroups
.
getLoggerGroup
(
"test"
)).
willReturn
(
Collections
.
singletonList
(
"test.member"
));
new
LoggersEndpoint
(
this
.
loggingSystem
,
this
.
loggingGroups
).
configureLogLevel
(
"test"
,
null
);
verify
(
this
.
loggingGroups
).
setLoggerGroupLevel
(
"test"
,
null
);
new
LoggersEndpoint
(
this
.
loggingSystem
,
this
.
loggerGroups
).
configureLogLevel
(
"test"
,
null
);
verify
(
this
.
loggingSystem
).
setLogLevel
(
"test.member"
,
null
);
}
// @Test
// void
}
spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/logging/LoggersEndpointWebIntegrationTests.java
View file @
61b86ff2
...
...
@@ -19,6 +19,9 @@ package org.springframework.boot.actuate.logging;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.EnumSet
;
import
java.util.LinkedHashMap
;
import
java.util.List
;
import
java.util.Map
;
import
net.minidev.json.JSONArray
;
import
org.hamcrest.collection.IsIterableContainingInAnyOrder
;
...
...
@@ -31,7 +34,7 @@ import org.springframework.boot.actuate.endpoint.http.ActuatorMediaType;
import
org.springframework.boot.actuate.endpoint.web.test.WebEndpointTest
;
import
org.springframework.boot.logging.LogLevel
;
import
org.springframework.boot.logging.LoggerConfiguration
;
import
org.springframework.boot.logging.Logg
ing
Groups
;
import
org.springframework.boot.logging.Logg
er
Groups
;
import
org.springframework.boot.logging.LoggingSystem
;
import
org.springframework.context.ConfigurableApplicationContext
;
import
org.springframework.context.annotation.Bean
;
...
...
@@ -54,6 +57,7 @@ import static org.mockito.Mockito.verifyZeroInteractions;
* @author Stephane Nicoll
* @author Andy Wilkinson
* @author HaiTao Zhang
* @author Madhura Bhave
*/
class
LoggersEndpointWebIntegrationTests
{
...
...
@@ -61,41 +65,21 @@ class LoggersEndpointWebIntegrationTests {
private
LoggingSystem
loggingSystem
;
private
LoggingGroups
loggingGroups
;
private
ObjectProvider
<
LoggingGroups
>
loggingGroupsObjectProvider
;
private
LoggerGroups
loggerGroups
;
@BeforeEach
@AfterEach
void
resetMocks
(
ConfigurableApplicationContext
context
,
WebTestClient
client
)
{
this
.
client
=
client
;
this
.
loggingSystem
=
context
.
getBean
(
LoggingSystem
.
class
);
this
.
loggingGroups
=
context
.
getBean
(
LoggingGroups
.
class
);
this
.
loggingGroupsObjectProvider
=
context
.
getBean
(
ObjectProvider
.
class
);
this
.
loggerGroups
=
context
.
getBean
(
LoggerGroups
.
class
);
Mockito
.
reset
(
this
.
loggingSystem
);
Mockito
.
reset
(
this
.
loggingGroups
);
given
(
this
.
loggingSystem
.
getSupportedLogLevels
()).
willReturn
(
EnumSet
.
allOf
(
LogLevel
.
class
));
given
(
this
.
loggingGroupsObjectProvider
.
getIfAvailable
()).
willReturn
(
this
.
loggingGroups
);
}
@WebEndpointTest
void
getLoggerShouldReturnAllLoggerConfigurations
()
{
given
(
this
.
loggingGroups
.
getLoggerGroupNames
()).
willReturn
(
null
);
given
(
this
.
loggingSystem
.
getLoggerConfigurations
())
.
willReturn
(
Collections
.
singletonList
(
new
LoggerConfiguration
(
"ROOT"
,
null
,
LogLevel
.
DEBUG
)));
this
.
client
.
get
().
uri
(
"/actuator/loggers"
).
exchange
().
expectStatus
().
isOk
().
expectBody
().
jsonPath
(
"$.length()"
)
.
isEqualTo
(
2
).
jsonPath
(
"levels"
)
.
isEqualTo
(
jsonArrayOf
(
"OFF"
,
"FATAL"
,
"ERROR"
,
"WARN"
,
"INFO"
,
"DEBUG"
,
"TRACE"
))
.
jsonPath
(
"loggers.length()"
).
isEqualTo
(
1
).
jsonPath
(
"loggers.ROOT.length()"
).
isEqualTo
(
2
)
.
jsonPath
(
"loggers.ROOT.configuredLevel"
).
isEqualTo
(
null
).
jsonPath
(
"loggers.ROOT.effectiveLevel"
)
.
isEqualTo
(
"DEBUG"
);
}
@WebEndpointTest
void
getLoggerShouldReturnAllLoggerConfigurationsWithLoggerGroups
()
{
given
(
this
.
loggingGroups
.
getLoggerGroupNames
()).
willReturn
(
Collections
.
singleton
(
"test"
));
given
(
this
.
loggingGroups
.
getLoggerGroup
(
"test"
)).
willReturn
(
Arrays
.
asList
(
"test.member1"
,
"test.member2"
));
given
(
this
.
loggingGroups
.
getLoggerGroupConfiguredLevel
(
"test"
)).
willReturn
(
LogLevel
.
DEBUG
);
setLogLevelToDebug
(
"test"
);
given
(
this
.
loggingSystem
.
getLoggerConfigurations
())
.
willReturn
(
Collections
.
singletonList
(
new
LoggerConfiguration
(
"ROOT"
,
null
,
LogLevel
.
DEBUG
)));
this
.
client
.
get
().
uri
(
"/actuator/loggers"
).
exchange
().
expectStatus
().
isOk
().
expectBody
().
jsonPath
(
"$.length()"
)
...
...
@@ -103,15 +87,13 @@ class LoggersEndpointWebIntegrationTests {
.
isEqualTo
(
jsonArrayOf
(
"OFF"
,
"FATAL"
,
"ERROR"
,
"WARN"
,
"INFO"
,
"DEBUG"
,
"TRACE"
))
.
jsonPath
(
"loggers.length()"
).
isEqualTo
(
1
).
jsonPath
(
"loggers.ROOT.length()"
).
isEqualTo
(
2
)
.
jsonPath
(
"loggers.ROOT.configuredLevel"
).
isEqualTo
(
null
).
jsonPath
(
"loggers.ROOT.effectiveLevel"
)
.
isEqualTo
(
"DEBUG"
).
jsonPath
(
"groups.length()"
).
isEqualTo
(
1
).
jsonPath
(
"groups.test.length()"
)
.
isEqualTo
(
2
).
jsonPath
(
"groups.test.configuredLevel"
).
isEqualTo
(
"DEBUG"
)
.
jsonPath
(
"groups.test.members.length()"
).
isEqualTo
(
2
).
jsonPath
(
"groups.test.members"
)
.
value
(
IsIterableContainingInAnyOrder
.
containsInAnyOrder
(
"test.member1"
,
"test.member2"
));
.
isEqualTo
(
"DEBUG"
).
jsonPath
(
"groups.length()"
).
isEqualTo
(
2
).
jsonPath
(
"groups.test.configuredLevel"
)
.
isEqualTo
(
"DEBUG"
);
}
@WebEndpointTest
void
getLoggerShouldReturnLogLevels
()
{
given
(
this
.
loggingGroups
.
isGroup
(
"ROOT"
)).
willReturn
(
false
);
setLogLevelToDebug
(
"test"
);
given
(
this
.
loggingSystem
.
getLoggerConfiguration
(
"ROOT"
))
.
willReturn
(
new
LoggerConfiguration
(
"ROOT"
,
null
,
LogLevel
.
DEBUG
));
this
.
client
.
get
().
uri
(
"/actuator/loggers/ROOT"
).
exchange
().
expectStatus
().
isOk
().
expectBody
()
...
...
@@ -126,9 +108,7 @@ class LoggersEndpointWebIntegrationTests {
@WebEndpointTest
void
getLoggerGroupShouldReturnConfiguredLogLevelAndMembers
()
{
given
(
this
.
loggingGroups
.
isGroup
(
"test"
)).
willReturn
(
true
);
given
(
this
.
loggingGroups
.
getLoggerGroupConfiguredLevel
(
"test"
)).
willReturn
(
LogLevel
.
DEBUG
);
given
(
this
.
loggingGroups
.
getLoggerGroup
(
"test"
)).
willReturn
(
Arrays
.
asList
(
"test.member1"
,
"test.member2"
));
setLogLevelToDebug
(
"test"
);
this
.
client
.
get
().
uri
(
"actuator/loggers/test"
).
exchange
().
expectStatus
().
isOk
().
expectBody
()
.
jsonPath
(
"$.length()"
).
isEqualTo
(
2
).
jsonPath
(
"members"
)
.
value
(
IsIterableContainingInAnyOrder
.
containsInAnyOrder
(
"test.member1"
,
"test.member2"
))
...
...
@@ -137,7 +117,6 @@ class LoggersEndpointWebIntegrationTests {
@WebEndpointTest
void
setLoggerUsingApplicationJsonShouldSetLogLevel
()
{
given
(
this
.
loggingGroups
.
isGroup
(
"ROOT"
)).
willReturn
(
false
);
this
.
client
.
post
().
uri
(
"/actuator/loggers/ROOT"
).
contentType
(
MediaType
.
APPLICATION_JSON
)
.
body
(
Collections
.
singletonMap
(
"configuredLevel"
,
"debug"
)).
exchange
().
expectStatus
().
isNoContent
();
verify
(
this
.
loggingSystem
).
setLogLevel
(
"ROOT"
,
LogLevel
.
DEBUG
);
...
...
@@ -145,7 +124,6 @@ class LoggersEndpointWebIntegrationTests {
@WebEndpointTest
void
setLoggerUsingActuatorV2JsonShouldSetLogLevel
()
{
given
(
this
.
loggingGroups
.
isGroup
(
"ROOT"
)).
willReturn
(
false
);
this
.
client
.
post
().
uri
(
"/actuator/loggers/ROOT"
)
.
contentType
(
MediaType
.
parseMediaType
(
ActuatorMediaType
.
V2_JSON
))
.
body
(
Collections
.
singletonMap
(
"configuredLevel"
,
"debug"
)).
exchange
().
expectStatus
().
isNoContent
();
...
...
@@ -154,21 +132,19 @@ class LoggersEndpointWebIntegrationTests {
@WebEndpointTest
void
setLoggerGroupUsingActuatorV2JsonShouldSetLogLevel
()
{
given
(
this
.
loggingGroups
.
isGroup
(
"test"
)).
willReturn
(
true
);
given
(
this
.
loggingGroups
.
getLoggerGroup
(
"test"
)).
willReturn
(
Arrays
.
asList
(
"test.member1"
,
"test.member2"
));
this
.
client
.
post
().
uri
(
"/actuator/loggers/test"
)
.
contentType
(
MediaType
.
parseMediaType
(
ActuatorMediaType
.
V2_JSON
))
.
body
(
Collections
.
singletonMap
(
"configuredLevel"
,
"debug"
)).
exchange
().
expectStatus
().
isNoContent
();
verify
(
this
.
loggingGroups
).
setLoggerGroupLevel
(
"test"
,
LogLevel
.
DEBUG
);
verify
(
this
.
loggingSystem
).
setLogLevel
(
"test.member1"
,
LogLevel
.
DEBUG
);
verify
(
this
.
loggingSystem
).
setLogLevel
(
"test.member2"
,
LogLevel
.
DEBUG
);
}
@WebEndpointTest
void
setLoggerGroupUsingApplicationJsonShouldSetLogLevel
()
{
given
(
this
.
loggingGroups
.
isGroup
(
"test"
)).
willReturn
(
true
);
given
(
this
.
loggingGroups
.
getLoggerGroup
(
"test"
)).
willReturn
(
Arrays
.
asList
(
"test.member1"
,
"test.member2"
));
this
.
client
.
post
().
uri
(
"/actuator/loggers/test"
).
contentType
(
MediaType
.
APPLICATION_JSON
)
.
body
(
Collections
.
singletonMap
(
"configuredLevel"
,
"debug"
)).
exchange
().
expectStatus
().
isNoContent
();
verify
(
this
.
loggingGroups
).
setLoggerGroupLevel
(
"test"
,
LogLevel
.
DEBUG
);
verify
(
this
.
loggingSystem
).
setLogLevel
(
"test.member1"
,
LogLevel
.
DEBUG
);
verify
(
this
.
loggingSystem
).
setLogLevel
(
"test.member2"
,
LogLevel
.
DEBUG
);
}
@WebEndpointTest
...
...
@@ -180,7 +156,6 @@ class LoggersEndpointWebIntegrationTests {
@WebEndpointTest
void
setLoggerWithNullLogLevel
()
{
given
(
this
.
loggingGroups
.
isGroup
(
"ROOT"
)).
willReturn
(
false
);
this
.
client
.
post
().
uri
(
"/actuator/loggers/ROOT"
)
.
contentType
(
MediaType
.
parseMediaType
(
ActuatorMediaType
.
V2_JSON
))
.
body
(
Collections
.
singletonMap
(
"configuredLevel"
,
null
)).
exchange
().
expectStatus
().
isNoContent
();
...
...
@@ -189,7 +164,6 @@ class LoggersEndpointWebIntegrationTests {
@WebEndpointTest
void
setLoggerWithNoLogLevel
()
{
given
(
this
.
loggingGroups
.
isGroup
(
"ROOT"
)).
willReturn
(
false
);
this
.
client
.
post
().
uri
(
"/actuator/loggers/ROOT"
)
.
contentType
(
MediaType
.
parseMediaType
(
ActuatorMediaType
.
V2_JSON
)).
body
(
Collections
.
emptyMap
())
.
exchange
().
expectStatus
().
isNoContent
();
...
...
@@ -198,22 +172,20 @@ class LoggersEndpointWebIntegrationTests {
@WebEndpointTest
void
setLoggerGroupWithNullLogLevel
()
{
given
(
this
.
loggingGroups
.
isGroup
(
"test"
)).
willReturn
(
true
);
given
(
this
.
loggingGroups
.
getLoggerGroup
(
"test"
)).
willReturn
(
Arrays
.
asList
(
"test.member1"
,
"test.member2"
));
this
.
client
.
post
().
uri
(
"/actuator/loggers/test"
)
.
contentType
(
MediaType
.
parseMediaType
(
ActuatorMediaType
.
V2_JSON
))
.
body
(
Collections
.
singletonMap
(
"configuredLevel"
,
null
)).
exchange
().
expectStatus
().
isNoContent
();
verify
(
this
.
loggingGroups
).
setLoggerGroupLevel
(
"test"
,
null
);
verify
(
this
.
loggingSystem
).
setLogLevel
(
"test.member1"
,
null
);
verify
(
this
.
loggingSystem
).
setLogLevel
(
"test.member2"
,
null
);
}
@WebEndpointTest
void
setLoggerGroupWithNoLogLevel
()
{
given
(
this
.
loggingGroups
.
isGroup
(
"test"
)).
willReturn
(
true
);
given
(
this
.
loggingGroups
.
getLoggerGroup
(
"test"
)).
willReturn
(
Arrays
.
asList
(
"test.member1"
,
"test.member2"
));
this
.
client
.
post
().
uri
(
"/actuator/loggers/test"
)
.
contentType
(
MediaType
.
parseMediaType
(
ActuatorMediaType
.
V2_JSON
)).
body
(
Collections
.
emptyMap
())
.
exchange
().
expectStatus
().
isNoContent
();
verify
(
this
.
loggingGroups
).
setLoggerGroupLevel
(
"test"
,
null
);
verify
(
this
.
loggingSystem
).
setLogLevel
(
"test.member1"
,
null
);
verify
(
this
.
loggingSystem
).
setLogLevel
(
"test.member2"
,
null
);
}
@WebEndpointTest
...
...
@@ -227,12 +199,15 @@ class LoggersEndpointWebIntegrationTests {
@WebEndpointTest
void
logLevelForLoggerGroupWithNameThatCouldBeMistakenForAPathExtension
()
{
given
(
this
.
loggingGroups
.
isGroup
(
"com.png"
)).
willReturn
(
true
);
given
(
this
.
loggingGroups
.
getLoggerGroupConfiguredLevel
(
"com.png"
)).
willReturn
(
LogLevel
.
DEBUG
);
given
(
this
.
loggingGroups
.
getLoggerGroup
(
"com.png"
)).
willReturn
(
Arrays
.
asList
(
"test.member1"
,
"test.member2"
));
this
.
client
.
get
().
uri
(
"/actuator/loggers/com.png"
).
exchange
().
expectStatus
().
isOk
().
expectBody
()
setLogLevelToDebug
(
"group.png"
);
this
.
client
.
get
().
uri
(
"/actuator/loggers/group.png"
).
exchange
().
expectStatus
().
isOk
().
expectBody
()
.
jsonPath
(
"$.length()"
).
isEqualTo
(
2
).
jsonPath
(
"configuredLevel"
).
isEqualTo
(
"DEBUG"
).
jsonPath
(
"members"
)
.
value
(
IsIterableContainingInAnyOrder
.
containsInAnyOrder
(
"test.member1"
,
"test.member2"
));
.
value
(
IsIterableContainingInAnyOrder
.
containsInAnyOrder
(
"png.member1"
,
"png.member2"
));
}
private
void
setLogLevelToDebug
(
String
name
)
{
this
.
loggerGroups
.
get
(
name
).
configureLogLevel
(
LogLevel
.
DEBUG
,
(
a
,
b
)
->
{
});
}
private
JSONArray
jsonArrayOf
(
Object
...
entries
)
{
...
...
@@ -250,18 +225,20 @@ class LoggersEndpointWebIntegrationTests {
}
@Bean
ObjectProvider
<
LoggingGroups
>
loggingGroupsObjectProvider
()
{
return
mock
(
ObjectProvider
.
class
);
LoggerGroups
loggingGroups
()
{
return
getLoggerGroups
(
);
}
@Bean
LoggingGroups
loggingGroups
()
{
return
mock
(
LoggingGroups
.
class
);
private
LoggerGroups
getLoggerGroups
()
{
Map
<
String
,
List
<
String
>>
groups
=
new
LinkedHashMap
<>();
groups
.
put
(
"test"
,
Arrays
.
asList
(
"test.member1"
,
"test.member2"
));
groups
.
put
(
"group.png"
,
Arrays
.
asList
(
"png.member1"
,
"png.member2"
));
return
new
LoggerGroups
(
groups
);
}
@Bean
LoggersEndpoint
endpoint
(
LoggingSystem
loggingSystem
,
ObjectProvider
<
Logg
ing
Groups
>
loggingGroupsObjectProvider
)
{
ObjectProvider
<
Logg
er
Groups
>
loggingGroupsObjectProvider
)
{
return
new
LoggersEndpoint
(
loggingSystem
,
loggingGroupsObjectProvider
.
getIfAvailable
());
}
...
...
spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/logging/LoggingApplicationListener.java
View file @
61b86ff2
...
...
@@ -16,12 +16,11 @@
package
org
.
springframework
.
boot
.
context
.
logging
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.LinkedHashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.concurrent.atomic.AtomicBoolean
;
import
java.util.function.BiConsumer
;
import
org.apache.commons.logging.Log
;
import
org.apache.commons.logging.LogFactory
;
...
...
@@ -37,7 +36,8 @@ import org.springframework.boot.context.properties.bind.Binder;
import
org.springframework.boot.context.properties.source.ConfigurationPropertyName
;
import
org.springframework.boot.logging.LogFile
;
import
org.springframework.boot.logging.LogLevel
;
import
org.springframework.boot.logging.LoggingGroups
;
import
org.springframework.boot.logging.LoggerGroup
;
import
org.springframework.boot.logging.LoggerGroups
;
import
org.springframework.boot.logging.LoggingInitializationContext
;
import
org.springframework.boot.logging.LoggingSystem
;
import
org.springframework.boot.logging.LoggingSystemProperties
;
...
...
@@ -52,7 +52,6 @@ import org.springframework.core.env.ConfigurableEnvironment;
import
org.springframework.core.env.Environment
;
import
org.springframework.util.LinkedMultiValueMap
;
import
org.springframework.util.MultiValueMap
;
import
org.springframework.util.ObjectUtils
;
import
org.springframework.util.ResourceUtils
;
import
org.springframework.util.StringUtils
;
...
...
@@ -85,6 +84,7 @@ import org.springframework.util.StringUtils;
* @author Phillip Webb
* @author Andy Wilkinson
* @author Madhura Bhave
* @author HaiTao Zhang
* @since 2.0.0
* @see LoggingSystem#get(ClassLoader)
*/
...
...
@@ -97,8 +97,8 @@ public class LoggingApplicationListener implements GenericApplicationListener {
private
static
final
Bindable
<
Map
<
String
,
LogLevel
>>
STRING_LOGLEVEL_MAP
=
Bindable
.
mapOf
(
String
.
class
,
LogLevel
.
class
);
private
static
final
Bindable
<
Map
<
String
,
String
[]>>
STRING_STRINGS_MAP
=
Bindable
.
mapOf
(
String
.
class
,
String
[].
class
);
private
static
final
Bindable
<
Map
<
String
,
List
<
String
>>>
STRING_STRINGS_MAP
=
Bindable
.
of
(
ResolvableType
.
forClassWithGenerics
(
MultiValueMap
.
class
,
String
.
class
,
String
.
class
).
asMap
()
);
/**
* The default order for the LoggingApplicationListener.
...
...
@@ -129,9 +129,10 @@ public class LoggingApplicationListener implements GenericApplicationListener {
public
static
final
String
LOGFILE_BEAN_NAME
=
"springBootLogFile"
;
/**
* The name of the{@link LoggingGroups} bean.
* The name of the{@link LoggerGroups} bean.
* @since 2.2.0
*/
public
static
final
String
LOGG
ING_GROUPS_BEAN_NAME
=
"springBootLogging
Groups"
;
public
static
final
String
LOGG
ER_GROUPS_BEAN_NAME
=
"springBootLogger
Groups"
;
private
static
final
Map
<
String
,
List
<
String
>>
DEFAULT_GROUP_LOGGERS
;
static
{
...
...
@@ -147,7 +148,7 @@ public class LoggingApplicationListener implements GenericApplicationListener {
DEFAULT_GROUP_LOGGERS
=
Collections
.
unmodifiableMap
(
loggers
);
}
private
static
final
Map
<
LogLevel
,
List
<
String
>>
LOG_LEVEL
_LOGGERS
;
private
static
final
Map
<
LogLevel
,
List
<
String
>>
SPRING_BOOT_LOGGING
_LOGGERS
;
static
{
MultiValueMap
<
LogLevel
,
String
>
loggers
=
new
LinkedMultiValueMap
<>();
loggers
.
add
(
LogLevel
.
DEBUG
,
"sql"
);
...
...
@@ -158,7 +159,7 @@ public class LoggingApplicationListener implements GenericApplicationListener {
loggers
.
add
(
LogLevel
.
TRACE
,
"org.apache.catalina"
);
loggers
.
add
(
LogLevel
.
TRACE
,
"org.eclipse.jetty"
);
loggers
.
add
(
LogLevel
.
TRACE
,
"org.hibernate.tool.hbm2ddl"
);
LOG_LEVEL
_LOGGERS
=
Collections
.
unmodifiableMap
(
loggers
);
SPRING_BOOT_LOGGING
_LOGGERS
=
Collections
.
unmodifiableMap
(
loggers
);
}
private
static
final
Class
<?>[]
EVENT_TYPES
=
{
ApplicationStartingEvent
.
class
,
...
...
@@ -173,10 +174,10 @@ public class LoggingApplicationListener implements GenericApplicationListener {
private
LoggingSystem
loggingSystem
;
private
LoggingGroups
loggingGroups
;
private
LogFile
logFile
;
private
LoggerGroups
loggerGroups
;
private
int
order
=
DEFAULT_ORDER
;
private
boolean
parseArgs
=
true
;
...
...
@@ -244,8 +245,8 @@ public class LoggingApplicationListener implements GenericApplicationListener {
if
(
this
.
logFile
!=
null
&&
!
beanFactory
.
containsBean
(
LOGFILE_BEAN_NAME
))
{
beanFactory
.
registerSingleton
(
LOGFILE_BEAN_NAME
,
this
.
logFile
);
}
if
(
this
.
logg
ingGroups
!=
null
&&
!
beanFactory
.
containsBean
(
LOGGING
_GROUPS_BEAN_NAME
))
{
beanFactory
.
registerSingleton
(
LOGG
ING_GROUPS_BEAN_NAME
,
this
.
logging
Groups
);
if
(
this
.
logg
erGroups
!=
null
&&
!
beanFactory
.
containsBean
(
LOGGER
_GROUPS_BEAN_NAME
))
{
beanFactory
.
registerSingleton
(
LOGG
ER_GROUPS_BEAN_NAME
,
this
.
logger
Groups
);
}
}
...
...
@@ -269,11 +270,11 @@ public class LoggingApplicationListener implements GenericApplicationListener {
*/
protected
void
initialize
(
ConfigurableEnvironment
environment
,
ClassLoader
classLoader
)
{
new
LoggingSystemProperties
(
environment
).
apply
();
this
.
loggingGroups
=
new
LoggingGroups
(
this
.
loggingSystem
);
this
.
logFile
=
LogFile
.
get
(
environment
);
if
(
this
.
logFile
!=
null
)
{
this
.
logFile
.
applyToSystemProperties
();
}
this
.
loggerGroups
=
new
LoggerGroups
(
DEFAULT_GROUP_LOGGERS
);
initializeEarlyLoggingLevel
(
environment
);
initializeSystem
(
environment
,
this
.
loggingSystem
,
this
.
logFile
);
initializeFinalLoggingLevels
(
environment
,
this
.
loggingSystem
);
...
...
@@ -321,70 +322,95 @@ public class LoggingApplicationListener implements GenericApplicationListener {
}
private
void
initializeFinalLoggingLevels
(
ConfigurableEnvironment
environment
,
LoggingSystem
system
)
{
bindLoggerGroups
(
environment
);
if
(
this
.
springBootLogging
!=
null
)
{
initializeLogLevel
(
system
,
this
.
springBootLogging
);
}
setLogLevels
(
system
,
environment
);
}
protected
void
initializeLogLevel
(
LoggingSystem
system
,
LogLevel
level
)
{
LOG_LEVEL_LOGGERS
.
getOrDefault
(
level
,
Collections
.
emptyList
())
.
forEach
((
logger
)
->
initializeLogLevel
(
system
,
level
,
logger
));
private
void
bindLoggerGroups
(
ConfigurableEnvironment
environment
)
{
if
(
this
.
loggerGroups
!=
null
)
{
Binder
binder
=
Binder
.
get
(
environment
);
binder
.
bind
(
LOGGING_GROUP
,
STRING_STRINGS_MAP
).
ifBound
(
this
.
loggerGroups
::
putAll
);
}
}
private
void
initializeLogLevel
(
LoggingSystem
system
,
LogLevel
level
,
String
logger
)
{
List
<
String
>
groupLoggers
=
DEFAULT_GROUP_LOGGERS
.
get
(
logger
);
if
(
groupLoggers
==
null
)
{
system
.
setLogLevel
(
logger
,
level
);
return
;
}
this
.
loggingGroups
.
setLoggerGroup
(
logger
,
groupLoggers
);
this
.
loggingGroups
.
setLoggerGroupLevel
(
logger
,
level
);
/**
* Initialize loggers based on the {@link #setSpringBootLogging(LogLevel)
* springBootLogging} setting.
* @param system the logging system
* @param springBootLogging the spring boot logging level requested
* @deprecated since 2.2.0 in favor of
* {@link #initializeSpringBootLogging(LoggingSystem, LogLevel)}
*/
@Deprecated
protected
void
initializeLogLevel
(
LoggingSystem
system
,
LogLevel
springBootLogging
)
{
initializeSpringBootLogging
(
system
,
springBootLogging
);
}
/**
* Initialize loggers based on the {@link #setSpringBootLogging(LogLevel)
* springBootLogging} setting. By default this implementation will pick an appropriate
* set of loggers to configure based on the level.
* @param system the logging system
* @param springBootLogging the spring boot logging level requested
* @since 2.2.0
*/
protected
void
initializeSpringBootLogging
(
LoggingSystem
system
,
LogLevel
springBootLogging
)
{
BiConsumer
<
String
,
LogLevel
>
configurer
=
getLogLevelConfigurer
(
system
);
SPRING_BOOT_LOGGING_LOGGERS
.
getOrDefault
(
springBootLogging
,
Collections
.
emptyList
())
.
forEach
((
name
)
->
configureLogLevel
(
name
,
springBootLogging
,
configurer
));
}
/**
* Set logging levels based on relevant {@link Environment} properties.
* @param system the logging system
* @param environment the environment
* @deprecated since 2.2.0 in favor of
* {@link #setLogLevels(LoggingSystem, ConfigurableEnvironment)}
*/
@Deprecated
protected
void
setLogLevels
(
LoggingSystem
system
,
Environment
environment
)
{
if
(
!(
environment
instanceof
ConfigurableEnvironment
)
)
{
return
;
if
(
environment
instanceof
ConfigurableEnvironment
)
{
setLogLevels
(
system
,
(
ConfigurableEnvironment
)
environment
)
;
}
Binder
binder
=
Binder
.
get
(
environment
);
Map
<
String
,
String
[]>
groups
=
getGroups
();
binder
.
bind
(
LOGGING_GROUP
,
STRING_STRINGS_MAP
.
withExistingValue
(
groups
));
Map
<
String
,
LogLevel
>
levels
=
binder
.
bind
(
LOGGING_LEVEL
,
STRING_LOGLEVEL_MAP
).
orElseGet
(
Collections:
:
emptyMap
);
levels
.
forEach
((
name
,
level
)
->
{
String
[]
groupedNames
=
groups
.
get
(
name
);
if
(
ObjectUtils
.
isEmpty
(
groupedNames
))
{
setLogLevel
(
system
,
name
,
level
);
}
else
{
setLogLevel
(
groupedNames
,
level
,
name
);
}
});
}
private
Map
<
String
,
String
[]>
getGroups
()
{
Map
<
String
,
String
[]>
groups
=
new
LinkedHashMap
<>();
DEFAULT_GROUP_LOGGERS
.
forEach
((
name
,
loggers
)
->
groups
.
put
(
name
,
StringUtils
.
toStringArray
(
loggers
)));
return
groups
;
/**
* Set logging levels based on relevant {@link Environment} properties.
* @param system the logging system
* @param environment the environment
* @since 2.2.0
*/
protected
void
setLogLevels
(
LoggingSystem
system
,
ConfigurableEnvironment
environment
)
{
BiConsumer
<
String
,
LogLevel
>
customizer
=
getLogLevelConfigurer
(
system
);
Binder
binder
=
Binder
.
get
(
environment
);
Map
<
String
,
LogLevel
>
levels
=
binder
.
bind
(
LOGGING_LEVEL
,
STRING_LOGLEVEL_MAP
).
orElseGet
(
Collections:
:
emptyMap
);
levels
.
forEach
((
name
,
level
)
->
configureLogLevel
(
name
,
level
,
customizer
));
}
private
void
setLogLevel
(
String
[]
names
,
LogLevel
level
,
String
groupName
)
{
try
{
this
.
loggingGroups
.
setLoggerGroup
(
groupName
,
Arrays
.
asList
(
names
)
);
this
.
loggingGroups
.
setLoggerGroupLevel
(
groupName
,
level
);
}
catch
(
RuntimeException
ex
)
{
this
.
logger
.
error
(
"Cannot set level '"
+
level
+
"' for '"
+
groupName
+
"'"
);
private
void
configureLogLevel
(
String
name
,
LogLevel
level
,
BiConsumer
<
String
,
LogLevel
>
configurer
)
{
if
(
this
.
loggerGroups
!=
null
)
{
LoggerGroup
group
=
this
.
loggerGroups
.
get
(
name
);
if
(
group
!=
null
&&
group
.
hasMembers
())
{
group
.
configureLogLevel
(
level
,
configurer
);
return
;
}
}
configurer
.
accept
(
name
,
level
);
}
private
void
setLogLevel
(
LoggingSystem
system
,
String
name
,
LogLevel
level
)
{
try
{
name
=
name
.
equalsIgnoreCase
(
LoggingSystem
.
ROOT_LOGGER_NAME
)
?
null
:
name
;
system
.
setLogLevel
(
name
,
level
);
}
catch
(
RuntimeException
ex
)
{
this
.
logger
.
error
(
"Cannot set level '"
+
level
+
"' for '"
+
name
+
"'"
);
}
private
BiConsumer
<
String
,
LogLevel
>
getLogLevelConfigurer
(
LoggingSystem
system
)
{
return
(
name
,
level
)
->
{
try
{
name
=
name
.
equalsIgnoreCase
(
LoggingSystem
.
ROOT_LOGGER_NAME
)
?
null
:
name
;
system
.
setLogLevel
(
name
,
level
);
}
catch
(
RuntimeException
ex
)
{
this
.
logger
.
error
(
"Cannot set level '"
+
level
+
"' for '"
+
name
+
"'"
);
}
};
}
private
void
registerShutdownHookIfNecessary
(
Environment
environment
,
LoggingSystem
loggingSystem
)
{
...
...
spring-boot-project/spring-boot/src/
test/java/org/springframework/boot/logging/LoggingGroupsTests
.java
→
spring-boot-project/spring-boot/src/
main/java/org/springframework/boot/logging/LoggerGroup
.java
View file @
61b86ff2
...
...
@@ -16,29 +16,50 @@
package
org
.
springframework
.
boot
.
logging
;
import
java.util.Arrays
;
import
org.junit.jupiter.api.Test
;
import
static
org
.
mockito
.
Mockito
.
mock
;
import
static
org
.
mockito
.
Mockito
.
verify
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.function.BiConsumer
;
/**
*
Tests for {@link LoggingGroups}
*
A single logger group.
*
* @author HaiTao Zhang
* @author Madhura Bhave
* @author Phillip Webb
* @since 2.2.0
*/
public
class
LoggingGroupsTests
{
public
final
class
LoggerGroup
{
private
final
String
name
;
private
final
List
<
String
>
members
;
private
LogLevel
configuredLevel
;
LoggerGroup
(
String
name
,
List
<
String
>
members
)
{
this
.
name
=
name
;
this
.
members
=
Collections
.
unmodifiableList
(
new
ArrayList
<>(
members
));
}
private
LoggingSystem
loggingSystem
=
mock
(
LoggingSystem
.
class
);
public
String
getName
()
{
return
this
.
name
;
}
public
List
<
String
>
getMembers
()
{
return
this
.
members
;
}
public
boolean
hasMembers
()
{
return
!
this
.
members
.
isEmpty
();
}
public
LogLevel
getConfiguredLevel
()
{
return
this
.
configuredLevel
;
}
@Test
void
setLoggerGroupWithTheConfiguredLevelToAllMembers
()
{
LoggingGroups
loggingGroups
=
new
LoggingGroups
(
this
.
loggingSystem
);
loggingGroups
.
setLoggerGroup
(
"test"
,
Arrays
.
asList
(
"test.member"
,
"test.member2"
));
loggingGroups
.
setLoggerGroupLevel
(
"test"
,
LogLevel
.
DEBUG
);
verify
(
this
.
loggingSystem
).
setLogLevel
(
"test.member2"
,
LogLevel
.
DEBUG
);
verify
(
this
.
loggingSystem
).
setLogLevel
(
"test.member"
,
LogLevel
.
DEBUG
);
public
void
configureLogLevel
(
LogLevel
level
,
BiConsumer
<
String
,
LogLevel
>
configurer
)
{
this
.
configuredLevel
=
level
;
this
.
members
.
forEach
((
name
)
->
configurer
.
accept
(
name
,
level
));
}
}
spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/LoggerGroups.java
0 → 100644
View file @
61b86ff2
/*
* Copyright 2012-2019 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
*
* https://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
.
logging
;
import
java.util.Iterator
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.concurrent.ConcurrentHashMap
;
/**
* Logger groups configured via the Spring Environment.
*
* @author HaiTao Zhang
* @author Phillip Webb
* @since 2.2.0 #see {@link LoggerGroup}
*/
public
final
class
LoggerGroups
implements
Iterable
<
LoggerGroup
>
{
private
final
Map
<
String
,
LoggerGroup
>
groups
=
new
ConcurrentHashMap
<>();
public
LoggerGroups
()
{
}
public
LoggerGroups
(
Map
<
String
,
List
<
String
>>
namesAndMembers
)
{
putAll
(
namesAndMembers
);
}
public
void
putAll
(
Map
<
String
,
List
<
String
>>
namesAndMembers
)
{
namesAndMembers
.
forEach
(
this
::
put
);
}
private
void
put
(
String
name
,
List
<
String
>
members
)
{
put
(
new
LoggerGroup
(
name
,
members
));
}
private
void
put
(
LoggerGroup
loggerGroup
)
{
this
.
groups
.
put
(
loggerGroup
.
getName
(),
loggerGroup
);
}
public
LoggerGroup
get
(
String
name
)
{
return
this
.
groups
.
get
(
name
);
}
@Override
public
Iterator
<
LoggerGroup
>
iterator
()
{
return
this
.
groups
.
values
().
iterator
();
}
}
spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/LoggingGroups.java
deleted
100644 → 0
View file @
b9047c22
/*
* Copyright 2012-2019 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
*
* https://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
.
logging
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.concurrent.ConcurrentHashMap
;
import
org.springframework.util.Assert
;
/**
* Manage logger groups.
*
* @author HaiTao Zhang
* @since 2.2.0
*/
public
class
LoggingGroups
{
private
Map
<
String
,
LogLevel
>
loggerGroupConfigurations
;
private
Map
<
String
,
List
<
String
>>
loggerGroups
;
private
LoggingSystem
loggingSystem
;
public
LoggingGroups
(
LoggingSystem
loggingSystem
)
{
this
.
loggerGroupConfigurations
=
new
ConcurrentHashMap
<>();
this
.
loggerGroups
=
new
ConcurrentHashMap
<>();
this
.
loggingSystem
=
loggingSystem
;
}
/**
* Associate a name to a list of logger's name to create a logger group.
* @param groupName name of the logger group
* @param members list of the members names
*/
public
void
setLoggerGroup
(
String
groupName
,
List
<
String
>
members
)
{
Assert
.
notNull
(
groupName
,
"Group name can not be null"
);
Assert
.
notNull
(
members
,
"Members can not be null"
);
this
.
loggerGroups
.
put
(
groupName
,
members
);
}
/**
* Set the logging level for a given logger group.
* @param groupName the name of the group to set
* @param level the log level ({@code null}) can be used to remove any custom level
* for the logger group and use the default configuration instead.
*/
public
void
setLoggerGroupLevel
(
String
groupName
,
LogLevel
level
)
{
Assert
.
notNull
(
groupName
,
"Group name can not be null"
);
List
<
String
>
members
=
this
.
loggerGroups
.
get
(
groupName
);
members
.
forEach
((
member
)
->
this
.
loggingSystem
.
setLogLevel
(
member
.
equalsIgnoreCase
(
LoggingSystem
.
ROOT_LOGGER_NAME
)
?
null
:
member
,
level
));
this
.
loggerGroupConfigurations
.
put
(
groupName
,
level
);
}
/**
* Checks whether a groupName is associated to a logger group.
* @param groupName name of the logger group
* @return a boolean stating true when groupName is associated with a group of loggers
*/
public
boolean
isGroup
(
String
groupName
)
{
Assert
.
notNull
(
groupName
,
"Group name can not be null"
);
return
this
.
loggerGroups
.
containsKey
(
groupName
);
}
/**
* Get the all registered logger groups.
* @return a Set of the names of the logger groups
*/
public
Set
<
String
>
getLoggerGroupNames
()
{
synchronized
(
this
)
{
return
this
.
loggerGroups
.
isEmpty
()
?
null
:
Collections
.
unmodifiableSet
(
this
.
loggerGroups
.
keySet
());
}
}
/**
* Get a logger group's members.
* @param groupName name of the logger group
* @return list of the members names associated with this group
*/
public
List
<
String
>
getLoggerGroup
(
String
groupName
)
{
Assert
.
notNull
(
groupName
,
"Group name can not be null"
);
return
Collections
.
unmodifiableList
(
this
.
loggerGroups
.
get
(
groupName
));
}
/**
* Get a logger group's configured level.
* @param groupName name of the logger group
* @return the logger groups configured level
*/
public
LogLevel
getLoggerGroupConfiguredLevel
(
String
groupName
)
{
Assert
.
notNull
(
groupName
,
"Group name can not be null"
);
return
this
.
loggerGroupConfigurations
.
get
(
groupName
);
}
}
spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/logging/LoggingApplicationListenerTests.java
View file @
61b86ff2
...
...
@@ -50,6 +50,7 @@ import org.springframework.boot.logging.AbstractLoggingSystem;
import
org.springframework.boot.logging.LogFile
;
import
org.springframework.boot.logging.LogLevel
;
import
org.springframework.boot.logging.LoggerConfiguration
;
import
org.springframework.boot.logging.LoggerGroups
;
import
org.springframework.boot.logging.LoggingInitializationContext
;
import
org.springframework.boot.logging.LoggingSystem
;
import
org.springframework.boot.logging.LoggingSystemProperties
;
...
...
@@ -284,6 +285,8 @@ class LoggingApplicationListenerTests {
this
.
loggerContext
.
getLogger
(
"org.hibernate.SQL"
).
debug
(
"testdebugsqlgroup"
);
assertThat
(
this
.
output
).
contains
(
"testdebugwebgroup"
);
assertThat
(
this
.
output
).
contains
(
"testdebugsqlgroup"
);
LoggerGroups
loggerGroups
=
(
LoggerGroups
)
ReflectionTestUtils
.
getField
(
this
.
initializer
,
"loggerGroups"
);
assertThat
(
loggerGroups
.
get
(
"web"
).
getConfiguredLevel
()).
isEqualTo
(
LogLevel
.
DEBUG
);
}
@Test
...
...
spring-boot-project/spring-boot/src/test/java/org/springframework/boot/logging/LoggerGroupsTests.java
0 → 100644
View file @
61b86ff2
/*
* Copyright 2012-2019 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
*
* https://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
.
logging
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.LinkedHashMap
;
import
java.util.List
;
import
java.util.Map
;
import
org.junit.jupiter.api.Test
;
import
static
org
.
assertj
.
core
.
api
.
Assertions
.
assertThat
;
import
static
org
.
mockito
.
Mockito
.
mock
;
/**
* Tests for {@link LoggerGroups}
*
* @author HaiTao Zhang
* @author Madhura Bhave
*/
class
LoggerGroupsTests
{
private
LoggingSystem
loggingSystem
=
mock
(
LoggingSystem
.
class
);
@Test
void
putAllShouldAddLoggerGroups
()
{
Map
<
String
,
List
<
String
>>
groups
=
Collections
.
singletonMap
(
"test"
,
Arrays
.
asList
(
"test.member"
,
"test.member2"
));
LoggerGroups
loggerGroups
=
new
LoggerGroups
();
loggerGroups
.
putAll
(
groups
);
LoggerGroup
group
=
loggerGroups
.
get
(
"test"
);
assertThat
(
group
.
getMembers
()).
containsExactly
(
"test.member"
,
"test.member2"
);
}
@Test
void
iteratorShouldReturnLoggerGroups
()
{
LoggerGroups
groups
=
createLoggerGroups
();
assertThat
(
groups
).
hasSize
(
3
);
assertThat
(
groups
).
extracting
(
"name"
).
containsExactlyInAnyOrder
(
"test0"
,
"test1"
,
"test2"
);
}
private
LoggerGroups
createLoggerGroups
()
{
Map
<
String
,
List
<
String
>>
groups
=
new
LinkedHashMap
<>();
groups
.
put
(
"test0"
,
Arrays
.
asList
(
"test0.member"
,
"test0.member2"
));
groups
.
put
(
"test1"
,
Arrays
.
asList
(
"test1.member"
,
"test1.member2"
));
groups
.
put
(
"test2"
,
Arrays
.
asList
(
"test2.member"
,
"test2.member2"
));
return
new
LoggerGroups
(
groups
);
}
}
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