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[]
...
@@ -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]]
[[loggers-setting-level]]
== Setting a Log Level
== Setting a Log Level
...
@@ -81,6 +96,30 @@ include::{snippets}loggers/set/request-fields.adoc[]
...
@@ -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]]
[[loggers-clearing-level]]
== Clearing a Log 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;
...
@@ -25,7 +25,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnBean
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnBean
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
;
import
org.springframework.boot.autoconfigure.condition.SpringBootCondition
;
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.boot.logging.LoggingSystem
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.ConditionContext
;
import
org.springframework.context.annotation.ConditionContext
;
...
@@ -48,8 +48,8 @@ public class LoggersEndpointAutoConfiguration {
...
@@ -48,8 +48,8 @@ public class LoggersEndpointAutoConfiguration {
@Conditional
(
OnEnabledLoggingSystemCondition
.
class
)
@Conditional
(
OnEnabledLoggingSystemCondition
.
class
)
@ConditionalOnMissingBean
@ConditionalOnMissingBean
public
LoggersEndpoint
loggersEndpoint
(
LoggingSystem
loggingSystem
,
public
LoggersEndpoint
loggersEndpoint
(
LoggingSystem
loggingSystem
,
ObjectProvider
<
Logg
ingGroups
>
loggingGroupsObjectProvider
)
{
ObjectProvider
<
Logg
erGroups
>
springBootLoggerGroups
)
{
return
new
LoggersEndpoint
(
loggingSystem
,
loggingGroupsObjectProvider
.
getIfAvailable
(
));
return
new
LoggersEndpoint
(
loggingSystem
,
springBootLoggerGroups
.
getIfAvailable
(
LoggerGroups:
:
new
));
}
}
static
class
OnEnabledLoggingSystemCondition
extends
SpringBootCondition
{
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;
...
@@ -20,14 +20,15 @@ import java.util.Arrays;
import
java.util.Collections
;
import
java.util.Collections
;
import
java.util.EnumSet
;
import
java.util.EnumSet
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
import
org.junit.jupiter.api.Test
;
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.actuate.logging.LoggersEndpoint
;
import
org.springframework.boot.logging.LogLevel
;
import
org.springframework.boot.logging.LogLevel
;
import
org.springframework.boot.logging.LoggerConfiguration
;
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.logging.LoggingSystem
;
import
org.springframework.boot.test.mock.mockito.MockBean
;
import
org.springframework.boot.test.mock.mockito.MockBean
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Bean
;
...
@@ -57,18 +58,20 @@ class LoggersEndpointDocumentationTests extends MockMvcEndpointDocumentationTest
...
@@ -57,18 +58,20 @@ class LoggersEndpointDocumentationTests extends MockMvcEndpointDocumentationTest
fieldWithPath
(
"configuredLevel"
).
description
(
"Configured level of the logger, if any."
).
optional
(),
fieldWithPath
(
"configuredLevel"
).
description
(
"Configured level of the logger, if any."
).
optional
(),
fieldWithPath
(
"effectiveLevel"
).
description
(
"Effective level of the logger."
));
fieldWithPath
(
"effectiveLevel"
).
description
(
"Effective level of the logger."
));
private
static
final
List
<
FieldDescriptor
>
groupLevelFields
=
Arrays
.
asList
(
private
static
final
List
<
FieldDescriptor
>
groupLevelFields
;
fieldWithPath
(
"configuredLevel"
).
description
(
"Configured level of the logger group"
),
fieldWithPath
(
"members"
).
description
(
"Loggers that are part of this group"
).
optional
());
@MockBean
static
{
private
LoggingSystem
loggingSystem
;
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
@MockBean
private
ObjectProvider
<
LoggingGroups
>
loggingGroupsObjectProvider
;
private
LoggingSystem
loggingSystem
;
@
MockBean
@
Autowired
LoggingGroups
logging
Groups
;
private
LoggerGroups
logger
Groups
;
@Test
@Test
void
allLoggers
()
throws
Exception
{
void
allLoggers
()
throws
Exception
{
...
@@ -76,10 +79,6 @@ class LoggersEndpointDocumentationTests extends MockMvcEndpointDocumentationTest
...
@@ -76,10 +79,6 @@ class LoggersEndpointDocumentationTests extends MockMvcEndpointDocumentationTest
given
(
this
.
loggingSystem
.
getLoggerConfigurations
())
given
(
this
.
loggingSystem
.
getLoggerConfigurations
())
.
willReturn
(
Arrays
.
asList
(
new
LoggerConfiguration
(
"ROOT"
,
LogLevel
.
INFO
,
LogLevel
.
INFO
),
.
willReturn
(
Arrays
.
asList
(
new
LoggerConfiguration
(
"ROOT"
,
LogLevel
.
INFO
,
LogLevel
.
INFO
),
new
LoggerConfiguration
(
"com.example"
,
LogLevel
.
DEBUG
,
LogLevel
.
DEBUG
)));
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
())
this
.
mockMvc
.
perform
(
get
(
"/actuator/loggers"
)).
andExpect
(
status
().
isOk
())
.
andDo
(
MockMvcRestDocumentation
.
document
(
"loggers/all"
,
.
andDo
(
MockMvcRestDocumentation
.
document
(
"loggers/all"
,
responseFields
(
fieldWithPath
(
"levels"
).
description
(
"Levels support by the logging system."
),
responseFields
(
fieldWithPath
(
"levels"
).
description
(
"Levels support by the logging system."
),
...
@@ -91,7 +90,6 @@ class LoggersEndpointDocumentationTests extends MockMvcEndpointDocumentationTest
...
@@ -91,7 +90,6 @@ class LoggersEndpointDocumentationTests extends MockMvcEndpointDocumentationTest
@Test
@Test
void
logger
()
throws
Exception
{
void
logger
()
throws
Exception
{
given
(
this
.
loggingGroupsObjectProvider
.
getIfAvailable
()).
willReturn
(
this
.
loggingGroups
);
given
(
this
.
loggingSystem
.
getLoggerConfiguration
(
"com.example"
))
given
(
this
.
loggingSystem
.
getLoggerConfiguration
(
"com.example"
))
.
willReturn
(
new
LoggerConfiguration
(
"com.example"
,
LogLevel
.
INFO
,
LogLevel
.
INFO
));
.
willReturn
(
new
LoggerConfiguration
(
"com.example"
,
LogLevel
.
INFO
,
LogLevel
.
INFO
));
this
.
mockMvc
.
perform
(
get
(
"/actuator/loggers/com.example"
)).
andExpect
(
status
().
isOk
())
this
.
mockMvc
.
perform
(
get
(
"/actuator/loggers/com.example"
)).
andExpect
(
status
().
isOk
())
...
@@ -100,17 +98,12 @@ class LoggersEndpointDocumentationTests extends MockMvcEndpointDocumentationTest
...
@@ -100,17 +98,12 @@ class LoggersEndpointDocumentationTests extends MockMvcEndpointDocumentationTest
@Test
@Test
void
loggerGroups
()
throws
Exception
{
void
loggerGroups
()
throws
Exception
{
given
(
this
.
loggingGroupsObjectProvider
.
getIfAvailable
()).
willReturn
(
this
.
loggingGroups
);
this
.
mockMvc
.
perform
(
get
(
"/actuator/loggers/test"
)).
andExpect
(
status
().
isOk
())
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
())
.
andDo
(
MockMvcRestDocumentation
.
document
(
"loggers/group"
,
responseFields
(
groupLevelFields
)));
.
andDo
(
MockMvcRestDocumentation
.
document
(
"loggers/group"
,
responseFields
(
groupLevelFields
)));
}
}
@Test
@Test
void
setLogLevel
()
throws
Exception
{
void
setLogLevel
()
throws
Exception
{
given
(
this
.
loggingGroupsObjectProvider
.
getIfAvailable
()).
willReturn
(
this
.
loggingGroups
);
this
.
mockMvc
this
.
mockMvc
.
perform
(
post
(
"/actuator/loggers/com.example"
).
content
(
"{\"configuredLevel\":\"debug\"}"
)
.
perform
(
post
(
"/actuator/loggers/com.example"
).
content
(
"{\"configuredLevel\":\"debug\"}"
)
.
contentType
(
MediaType
.
APPLICATION_JSON
))
.
contentType
(
MediaType
.
APPLICATION_JSON
))
...
@@ -122,22 +115,26 @@ class LoggersEndpointDocumentationTests extends MockMvcEndpointDocumentationTest
...
@@ -122,22 +115,26 @@ class LoggersEndpointDocumentationTests extends MockMvcEndpointDocumentationTest
@Test
@Test
void
setLogLevelOfLoggerGroup
()
throws
Exception
{
void
setLogLevelOfLoggerGroup
()
throws
Exception
{
given
(
this
.
loggingGroupsObjectProvider
.
getIfAvailable
()).
willReturn
(
this
.
loggingGroups
);
given
(
this
.
loggingGroups
.
isGroup
(
"com.example"
)).
willReturn
(
true
);
this
.
mockMvc
this
.
mockMvc
.
perform
(
post
(
"/actuator/loggers/
com.example
"
)
.
perform
(
post
(
"/actuator/loggers/
test
"
)
.
content
(
"{\"configuredLevel\":\"debug\"}"
).
contentType
(
MediaType
.
APPLICATION_JSON
))
.
content
(
"{\"configuredLevel\":\"debug\"}"
).
contentType
(
MediaType
.
APPLICATION_JSON
))
.
andExpect
(
status
().
isNoContent
()).
andDo
(
.
andExpect
(
status
().
isNoContent
()).
andDo
(
MockMvcRestDocumentation
.
document
(
"loggers/setGroup"
,
MockMvcRestDocumentation
.
document
(
"loggers/setGroup"
,
requestFields
(
fieldWithPath
(
"configuredLevel"
).
description
(
requestFields
(
fieldWithPath
(
"configuredLevel"
).
description
(
"Level for the logger group. May be omitted to clear the level of the loggers."
)
"Level for the logger group. May be omitted to clear the level of the loggers."
)
.
optional
())));
.
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
@Test
void
clearLogLevel
()
throws
Exception
{
void
clearLogLevel
()
throws
Exception
{
given
(
this
.
loggingGroupsObjectProvider
.
getIfAvailable
()).
willReturn
(
this
.
loggingGroups
);
this
.
mockMvc
this
.
mockMvc
.
perform
(
post
(
"/actuator/loggers/com.example"
).
content
(
"{}"
).
contentType
(
MediaType
.
APPLICATION_JSON
))
.
perform
(
post
(
"/actuator/loggers/com.example"
).
content
(
"{}"
).
contentType
(
MediaType
.
APPLICATION_JSON
))
.
andExpect
(
status
().
isNoContent
()).
andDo
(
MockMvcRestDocumentation
.
document
(
"loggers/clear"
));
.
andExpect
(
status
().
isNoContent
()).
andDo
(
MockMvcRestDocumentation
.
document
(
"loggers/clear"
));
...
@@ -149,9 +146,13 @@ class LoggersEndpointDocumentationTests extends MockMvcEndpointDocumentationTest
...
@@ -149,9 +146,13 @@ class LoggersEndpointDocumentationTests extends MockMvcEndpointDocumentationTest
static
class
TestConfiguration
{
static
class
TestConfiguration
{
@Bean
@Bean
LoggersEndpoint
endpoint
(
LoggingSystem
loggingSystem
,
LoggersEndpoint
endpoint
(
LoggingSystem
loggingSystem
,
LoggerGroups
groups
)
{
ObjectProvider
<
LoggingGroups
>
loggingGroupsObjectProvider
)
{
groups
.
putAll
(
getLoggerGroups
());
return
new
LoggersEndpoint
(
loggingSystem
,
loggingGroupsObjectProvider
.
getIfAvailable
());
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;
...
@@ -31,7 +31,8 @@ import org.springframework.boot.actuate.endpoint.annotation.Selector;
import
org.springframework.boot.actuate.endpoint.annotation.WriteOperation
;
import
org.springframework.boot.actuate.endpoint.annotation.WriteOperation
;
import
org.springframework.boot.logging.LogLevel
;
import
org.springframework.boot.logging.LogLevel
;
import
org.springframework.boot.logging.LoggerConfiguration
;
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.boot.logging.LoggingSystem
;
import
org.springframework.lang.Nullable
;
import
org.springframework.lang.Nullable
;
import
org.springframework.util.Assert
;
import
org.springframework.util.Assert
;
...
@@ -49,17 +50,18 @@ public class LoggersEndpoint {
...
@@ -49,17 +50,18 @@ public class LoggersEndpoint {
private
final
LoggingSystem
loggingSystem
;
private
final
LoggingSystem
loggingSystem
;
private
final
Logg
ingGroups
logging
Groups
;
private
final
Logg
erGroups
logger
Groups
;
/**
/**
* Create a new {@link LoggersEndpoint} instance.
* Create a new {@link LoggersEndpoint} instance.
* @param loggingSystem the logging system to expose
* @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
(
loggingSystem
,
"LoggingSystem must not be null"
);
Assert
.
notNull
(
loggerGroups
,
"LoggerGroups must not be null"
);
this
.
loggingSystem
=
loggingSystem
;
this
.
loggingSystem
=
loggingSystem
;
this
.
logg
ingGroups
=
logging
Groups
;
this
.
logg
erGroups
=
logger
Groups
;
}
}
@ReadOperation
@ReadOperation
...
@@ -71,20 +73,23 @@ public class LoggersEndpoint {
...
@@ -71,20 +73,23 @@ public class LoggersEndpoint {
Map
<
String
,
Object
>
result
=
new
LinkedHashMap
<>();
Map
<
String
,
Object
>
result
=
new
LinkedHashMap
<>();
result
.
put
(
"levels"
,
getLevels
());
result
.
put
(
"levels"
,
getLevels
());
result
.
put
(
"loggers"
,
getLoggers
(
configurations
));
result
.
put
(
"loggers"
,
getLoggers
(
configurations
));
if
(
this
.
loggingGroups
!=
null
&&
this
.
loggingGroups
.
getLoggerGroupNames
()
!=
null
)
{
result
.
put
(
"groups"
,
getGroups
());
Set
<
String
>
groups
=
this
.
loggingGroups
.
getLoggerGroupNames
();
result
.
put
(
"groups"
,
getLoggerGroups
(
groups
));
}
return
result
;
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
@ReadOperation
public
LoggerLevels
loggerLevels
(
@Selector
String
name
)
{
public
LoggerLevels
loggerLevels
(
@Selector
String
name
)
{
Assert
.
notNull
(
name
,
"Name must not be null"
);
Assert
.
notNull
(
name
,
"Name must not be null"
);
if
(
this
.
loggingGroups
!=
null
&&
this
.
loggingGroups
.
isGroup
(
name
))
{
LoggerGroup
group
=
this
.
loggerGroups
.
get
(
name
);
List
<
String
>
members
=
this
.
loggingGroups
.
getLoggerGroup
(
name
);
if
(
group
!=
null
)
{
LogLevel
groupConfiguredLevel
=
this
.
loggingGroups
.
getLoggerGroupConfiguredLevel
(
name
);
return
new
GroupLoggerLevels
(
group
.
getConfiguredLevel
(),
group
.
getMembers
());
return
new
GroupLoggerLevels
(
groupConfiguredLevel
,
members
);
}
}
LoggerConfiguration
configuration
=
this
.
loggingSystem
.
getLoggerConfiguration
(
name
);
LoggerConfiguration
configuration
=
this
.
loggingSystem
.
getLoggerConfiguration
(
name
);
return
(
configuration
!=
null
)
?
new
SingleLoggerLevels
(
configuration
)
:
null
;
return
(
configuration
!=
null
)
?
new
SingleLoggerLevels
(
configuration
)
:
null
;
...
@@ -93,8 +98,9 @@ public class LoggersEndpoint {
...
@@ -93,8 +98,9 @@ public class LoggersEndpoint {
@WriteOperation
@WriteOperation
public
void
configureLogLevel
(
@Selector
String
name
,
@Nullable
LogLevel
configuredLevel
)
{
public
void
configureLogLevel
(
@Selector
String
name
,
@Nullable
LogLevel
configuredLevel
)
{
Assert
.
notNull
(
name
,
"Name must not be empty"
);
Assert
.
notNull
(
name
,
"Name must not be empty"
);
if
(
this
.
loggingGroups
!=
null
&&
this
.
loggingGroups
.
isGroup
(
name
))
{
LoggerGroup
group
=
this
.
loggerGroups
.
get
(
name
);
this
.
loggingGroups
.
setLoggerGroupLevel
(
name
,
configuredLevel
);
if
(
group
!=
null
&&
group
.
hasMembers
())
{
group
.
configureLogLevel
(
configuredLevel
,
this
.
loggingSystem
::
setLogLevel
);
return
;
return
;
}
}
this
.
loggingSystem
.
setLogLevel
(
name
,
configuredLevel
);
this
.
loggingSystem
.
setLogLevel
(
name
,
configuredLevel
);
...
@@ -113,16 +119,6 @@ public class LoggersEndpoint {
...
@@ -113,16 +119,6 @@ public class LoggersEndpoint {
return
loggers
;
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.
* Levels configured for a given logger exposed in a JSON friendly way.
*/
*/
...
@@ -134,13 +130,12 @@ public class LoggersEndpoint {
...
@@ -134,13 +130,12 @@ public class LoggersEndpoint {
this
.
configuredLevel
=
getName
(
configuredLevel
);
this
.
configuredLevel
=
getName
(
configuredLevel
);
}
}
pr
ivate
String
getName
(
LogLevel
level
)
{
pr
otected
final
String
getName
(
LogLevel
level
)
{
return
(
level
!=
null
)
?
level
.
name
()
:
null
;
return
(
level
!=
null
)
?
level
.
name
()
:
null
;
}
}
public
String
getConfiguredLevel
()
{
public
String
getConfiguredLevel
()
{
return
this
.
configuredLevel
;
return
this
.
configuredLevel
;
}
}
}
}
...
@@ -166,7 +161,7 @@ public class LoggersEndpoint {
...
@@ -166,7 +161,7 @@ public class LoggersEndpoint {
public
SingleLoggerLevels
(
LoggerConfiguration
configuration
)
{
public
SingleLoggerLevels
(
LoggerConfiguration
configuration
)
{
super
(
configuration
.
getConfiguredLevel
());
super
(
configuration
.
getConfiguredLevel
());
this
.
effectiveLevel
=
super
.
getName
(
configuration
.
getEffectiveLevel
());
this
.
effectiveLevel
=
getName
(
configuration
.
getEffectiveLevel
());
}
}
public
String
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;
...
@@ -18,9 +18,11 @@ package org.springframework.boot.actuate.logging;
import
java.util.Collections
;
import
java.util.Collections
;
import
java.util.EnumSet
;
import
java.util.EnumSet
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.Set
;
import
org.junit.jupiter.api.BeforeEach
;
import
org.junit.jupiter.api.Test
;
import
org.junit.jupiter.api.Test
;
import
org.springframework.boot.actuate.logging.LoggersEndpoint.GroupLoggerLevels
;
import
org.springframework.boot.actuate.logging.LoggersEndpoint.GroupLoggerLevels
;
...
@@ -28,7 +30,7 @@ import org.springframework.boot.actuate.logging.LoggersEndpoint.LoggerLevels;
...
@@ -28,7 +30,7 @@ import org.springframework.boot.actuate.logging.LoggersEndpoint.LoggerLevels;
import
org.springframework.boot.actuate.logging.LoggersEndpoint.SingleLoggerLevels
;
import
org.springframework.boot.actuate.logging.LoggersEndpoint.SingleLoggerLevels
;
import
org.springframework.boot.logging.LogLevel
;
import
org.springframework.boot.logging.LogLevel
;
import
org.springframework.boot.logging.LoggerConfiguration
;
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.logging.LoggingSystem
;
import
static
org
.
assertj
.
core
.
api
.
Assertions
.
assertThat
;
import
static
org
.
assertj
.
core
.
api
.
Assertions
.
assertThat
;
...
@@ -42,12 +44,21 @@ import static org.mockito.Mockito.verify;
...
@@ -42,12 +44,21 @@ import static org.mockito.Mockito.verify;
* @author Ben Hale
* @author Ben Hale
* @author Andy Wilkinson
* @author Andy Wilkinson
* @author HaiTao Zhang
* @author HaiTao Zhang
* @author Madhura Bhave
*/
*/
class
LoggersEndpointTests
{
class
LoggersEndpointTests
{
private
final
LoggingSystem
loggingSystem
=
mock
(
LoggingSystem
.
class
);
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
@Test
@SuppressWarnings
(
"unchecked"
)
@SuppressWarnings
(
"unchecked"
)
...
@@ -55,8 +66,7 @@ class LoggersEndpointTests {
...
@@ -55,8 +66,7 @@ class LoggersEndpointTests {
given
(
this
.
loggingSystem
.
getLoggerConfigurations
())
given
(
this
.
loggingSystem
.
getLoggerConfigurations
())
.
willReturn
(
Collections
.
singletonList
(
new
LoggerConfiguration
(
"ROOT"
,
null
,
LogLevel
.
DEBUG
)));
.
willReturn
(
Collections
.
singletonList
(
new
LoggerConfiguration
(
"ROOT"
,
null
,
LogLevel
.
DEBUG
)));
given
(
this
.
loggingSystem
.
getSupportedLogLevels
()).
willReturn
(
EnumSet
.
allOf
(
LogLevel
.
class
));
given
(
this
.
loggingSystem
.
getSupportedLogLevels
()).
willReturn
(
EnumSet
.
allOf
(
LogLevel
.
class
));
given
(
this
.
loggingGroups
.
getLoggerGroupNames
()).
willReturn
(
null
);
Map
<
String
,
Object
>
result
=
new
LoggersEndpoint
(
this
.
loggingSystem
,
new
LoggerGroups
()).
loggers
();
Map
<
String
,
Object
>
result
=
new
LoggersEndpoint
(
this
.
loggingSystem
,
this
.
loggingGroups
).
loggers
();
Map
<
String
,
LoggerLevels
>
loggers
=
(
Map
<
String
,
LoggerLevels
>)
result
.
get
(
"loggers"
);
Map
<
String
,
LoggerLevels
>
loggers
=
(
Map
<
String
,
LoggerLevels
>)
result
.
get
(
"loggers"
);
Set
<
LogLevel
>
levels
=
(
Set
<
LogLevel
>)
result
.
get
(
"levels"
);
Set
<
LogLevel
>
levels
=
(
Set
<
LogLevel
>)
result
.
get
(
"levels"
);
SingleLoggerLevels
rootLevels
=
(
SingleLoggerLevels
)
loggers
.
get
(
"ROOT"
);
SingleLoggerLevels
rootLevels
=
(
SingleLoggerLevels
)
loggers
.
get
(
"ROOT"
);
...
@@ -64,7 +74,8 @@ class LoggersEndpointTests {
...
@@ -64,7 +74,8 @@ class LoggersEndpointTests {
assertThat
(
rootLevels
.
getEffectiveLevel
()).
isEqualTo
(
"DEBUG"
);
assertThat
(
rootLevels
.
getEffectiveLevel
()).
isEqualTo
(
"DEBUG"
);
assertThat
(
levels
).
containsExactly
(
LogLevel
.
OFF
,
LogLevel
.
FATAL
,
LogLevel
.
ERROR
,
LogLevel
.
WARN
,
LogLevel
.
INFO
,
assertThat
(
levels
).
containsExactly
(
LogLevel
.
OFF
,
LogLevel
.
FATAL
,
LogLevel
.
ERROR
,
LogLevel
.
WARN
,
LogLevel
.
INFO
,
LogLevel
.
DEBUG
,
LogLevel
.
TRACE
);
LogLevel
.
DEBUG
,
LogLevel
.
TRACE
);
assertThat
(
result
.
get
(
"groups"
)).
isNull
();
Map
<
String
,
LoggerGroups
>
groups
=
(
Map
<
String
,
LoggerGroups
>)
result
.
get
(
"groups"
);
assertThat
(
groups
).
isEmpty
();
}
}
@Test
@Test
...
@@ -73,12 +84,9 @@ class LoggersEndpointTests {
...
@@ -73,12 +84,9 @@ class LoggersEndpointTests {
given
(
this
.
loggingSystem
.
getLoggerConfigurations
())
given
(
this
.
loggingSystem
.
getLoggerConfigurations
())
.
willReturn
(
Collections
.
singletonList
(
new
LoggerConfiguration
(
"ROOT"
,
null
,
LogLevel
.
DEBUG
)));
.
willReturn
(
Collections
.
singletonList
(
new
LoggerConfiguration
(
"ROOT"
,
null
,
LogLevel
.
DEBUG
)));
given
(
this
.
loggingSystem
.
getSupportedLogLevels
()).
willReturn
(
EnumSet
.
allOf
(
LogLevel
.
class
));
given
(
this
.
loggingSystem
.
getSupportedLogLevels
()).
willReturn
(
EnumSet
.
allOf
(
LogLevel
.
class
));
given
(
this
.
loggingGroups
.
getLoggerGroup
(
"test"
)).
willReturn
(
Collections
.
singletonList
(
"test.member"
));
Map
<
String
,
Object
>
result
=
new
LoggersEndpoint
(
this
.
loggingSystem
,
this
.
loggerGroups
).
loggers
();
given
(
this
.
loggingGroups
.
getLoggerGroupNames
()).
willReturn
(
Collections
.
singleton
(
"test"
));
Map
<
String
,
GroupLoggerLevels
>
loggerGroups
=
(
Map
<
String
,
GroupLoggerLevels
>)
result
.
get
(
"groups"
);
given
(
this
.
loggingGroups
.
getLoggerGroupConfiguredLevel
(
"test"
)).
willReturn
(
LogLevel
.
DEBUG
);
GroupLoggerLevels
groupLevel
=
loggerGroups
.
get
(
"test"
);
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
,
LoggerLevels
>
loggers
=
(
Map
<
String
,
LoggerLevels
>)
result
.
get
(
"loggers"
);
Map
<
String
,
LoggerLevels
>
loggers
=
(
Map
<
String
,
LoggerLevels
>)
result
.
get
(
"loggers"
);
Set
<
LogLevel
>
levels
=
(
Set
<
LogLevel
>)
result
.
get
(
"levels"
);
Set
<
LogLevel
>
levels
=
(
Set
<
LogLevel
>)
result
.
get
(
"levels"
);
SingleLoggerLevels
rootLevels
=
(
SingleLoggerLevels
)
loggers
.
get
(
"ROOT"
);
SingleLoggerLevels
rootLevels
=
(
SingleLoggerLevels
)
loggers
.
get
(
"ROOT"
);
...
@@ -87,17 +95,15 @@ class LoggersEndpointTests {
...
@@ -87,17 +95,15 @@ class LoggersEndpointTests {
assertThat
(
levels
).
containsExactly
(
LogLevel
.
OFF
,
LogLevel
.
FATAL
,
LogLevel
.
ERROR
,
LogLevel
.
WARN
,
LogLevel
.
INFO
,
assertThat
(
levels
).
containsExactly
(
LogLevel
.
OFF
,
LogLevel
.
FATAL
,
LogLevel
.
ERROR
,
LogLevel
.
WARN
,
LogLevel
.
INFO
,
LogLevel
.
DEBUG
,
LogLevel
.
TRACE
);
LogLevel
.
DEBUG
,
LogLevel
.
TRACE
);
assertThat
(
loggerGroups
).
isNotNull
();
assertThat
(
loggerGroups
).
isNotNull
();
assertThat
(
testLoggerLevel
).
isNotNull
();
assertThat
(
groupLevel
.
getConfiguredLevel
()).
isEqualTo
(
"DEBUG"
);
assertThat
(
testLoggerLevel
.
getConfiguredLevel
()).
isEqualTo
(
"DEBUG"
);
assertThat
(
groupLevel
.
getMembers
()).
containsExactly
(
"test.member"
);
assertThat
(
testLoggerLevel
.
getMembers
()).
isEqualTo
(
Collections
.
singletonList
(
"test.member"
));
}
}
@Test
@Test
void
loggerLevelsWhenNameSpecifiedShouldReturnLevels
()
{
void
loggerLevelsWhenNameSpecifiedShouldReturnLevels
()
{
given
(
this
.
loggingGroups
.
isGroup
(
"ROOT"
)).
willReturn
(
false
);
given
(
this
.
loggingSystem
.
getLoggerConfiguration
(
"ROOT"
))
given
(
this
.
loggingSystem
.
getLoggerConfiguration
(
"ROOT"
))
.
willReturn
(
new
LoggerConfiguration
(
"ROOT"
,
null
,
LogLevel
.
DEBUG
));
.
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"
);
.
loggerLevels
(
"ROOT"
);
assertThat
(
levels
.
getConfiguredLevel
()).
isNull
();
assertThat
(
levels
.
getConfiguredLevel
()).
isNull
();
assertThat
(
levels
.
getEffectiveLevel
()).
isEqualTo
(
"DEBUG"
);
assertThat
(
levels
.
getEffectiveLevel
()).
isEqualTo
(
"DEBUG"
);
...
@@ -105,10 +111,7 @@ class LoggersEndpointTests {
...
@@ -105,10 +111,7 @@ class LoggersEndpointTests {
@Test
@Test
void
groupNameSpecifiedShouldReturnConfiguredLevelAndMembers
()
{
void
groupNameSpecifiedShouldReturnConfiguredLevelAndMembers
()
{
given
(
this
.
loggingGroups
.
isGroup
(
"test"
)).
willReturn
(
true
);
GroupLoggerLevels
levels
=
(
GroupLoggerLevels
)
new
LoggersEndpoint
(
this
.
loggingSystem
,
this
.
loggerGroups
)
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
)
.
loggerLevels
(
"test"
);
.
loggerLevels
(
"test"
);
assertThat
(
levels
.
getConfiguredLevel
()).
isEqualTo
(
"DEBUG"
);
assertThat
(
levels
.
getConfiguredLevel
()).
isEqualTo
(
"DEBUG"
);
assertThat
(
levels
.
getMembers
()).
isEqualTo
(
Collections
.
singletonList
(
"test.member"
));
assertThat
(
levels
.
getMembers
()).
isEqualTo
(
Collections
.
singletonList
(
"test.member"
));
...
@@ -116,35 +119,26 @@ class LoggersEndpointTests {
...
@@ -116,35 +119,26 @@ class LoggersEndpointTests {
@Test
@Test
void
configureLogLevelShouldSetLevelOnLoggingSystem
()
{
void
configureLogLevelShouldSetLevelOnLoggingSystem
()
{
given
(
this
.
loggingGroups
.
getLoggerGroup
(
"ROOT"
)).
willReturn
(
null
);
new
LoggersEndpoint
(
this
.
loggingSystem
,
this
.
loggerGroups
).
configureLogLevel
(
"ROOT"
,
LogLevel
.
DEBUG
);
new
LoggersEndpoint
(
this
.
loggingSystem
,
this
.
loggingGroups
).
configureLogLevel
(
"ROOT"
,
LogLevel
.
DEBUG
);
verify
(
this
.
loggingSystem
).
setLogLevel
(
"ROOT"
,
LogLevel
.
DEBUG
);
verify
(
this
.
loggingSystem
).
setLogLevel
(
"ROOT"
,
LogLevel
.
DEBUG
);
}
}
@Test
@Test
void
configureLogLevelWithNullSetsLevelOnLoggingSystemToNull
()
{
void
configureLogLevelWithNullSetsLevelOnLoggingSystemToNull
()
{
given
(
this
.
loggingGroups
.
getLoggerGroup
(
"ROOT"
)).
willReturn
(
null
);
new
LoggersEndpoint
(
this
.
loggingSystem
,
this
.
loggerGroups
).
configureLogLevel
(
"ROOT"
,
null
);
new
LoggersEndpoint
(
this
.
loggingSystem
,
this
.
loggingGroups
).
configureLogLevel
(
"ROOT"
,
null
);
verify
(
this
.
loggingSystem
).
setLogLevel
(
"ROOT"
,
null
);
verify
(
this
.
loggingSystem
).
setLogLevel
(
"ROOT"
,
null
);
}
}
@Test
@Test
void
configureLogLevelInLoggerGroupShouldSetLevelOnLoggingSystem
()
{
void
configureLogLevelInLoggerGroupShouldSetLevelOnLoggingSystem
()
{
given
(
this
.
loggingGroups
.
isGroup
(
"test"
)).
willReturn
(
true
);
new
LoggersEndpoint
(
this
.
loggingSystem
,
this
.
loggerGroups
).
configureLogLevel
(
"test"
,
LogLevel
.
DEBUG
);
given
(
this
.
loggingGroups
.
getLoggerGroup
(
"test"
)).
willReturn
(
Collections
.
singletonList
(
"test.member"
));
verify
(
this
.
loggingSystem
).
setLogLevel
(
"test.member"
,
LogLevel
.
DEBUG
);
new
LoggersEndpoint
(
this
.
loggingSystem
,
this
.
loggingGroups
).
configureLogLevel
(
"test"
,
LogLevel
.
DEBUG
);
verify
(
this
.
loggingGroups
).
setLoggerGroupLevel
(
"test"
,
LogLevel
.
DEBUG
);
}
}
@Test
@Test
void
configureLogLevelWithNullInLoggerGroupShouldSetLevelOnLoggingSystem
()
{
void
configureLogLevelWithNullInLoggerGroupShouldSetLevelOnLoggingSystem
()
{
given
(
this
.
loggingGroups
.
isGroup
(
"test"
)).
willReturn
(
true
);
new
LoggersEndpoint
(
this
.
loggingSystem
,
this
.
loggerGroups
).
configureLogLevel
(
"test"
,
null
);
given
(
this
.
loggingGroups
.
getLoggerGroup
(
"test"
)).
willReturn
(
Collections
.
singletonList
(
"test.member"
));
verify
(
this
.
loggingSystem
).
setLogLevel
(
"test.member"
,
null
);
new
LoggersEndpoint
(
this
.
loggingSystem
,
this
.
loggingGroups
).
configureLogLevel
(
"test"
,
null
);
verify
(
this
.
loggingGroups
).
setLoggerGroupLevel
(
"test"
,
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;
...
@@ -19,6 +19,9 @@ package org.springframework.boot.actuate.logging;
import
java.util.Arrays
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.Collections
;
import
java.util.EnumSet
;
import
java.util.EnumSet
;
import
java.util.LinkedHashMap
;
import
java.util.List
;
import
java.util.Map
;
import
net.minidev.json.JSONArray
;
import
net.minidev.json.JSONArray
;
import
org.hamcrest.collection.IsIterableContainingInAnyOrder
;
import
org.hamcrest.collection.IsIterableContainingInAnyOrder
;
...
@@ -31,7 +34,7 @@ import org.springframework.boot.actuate.endpoint.http.ActuatorMediaType;
...
@@ -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.actuate.endpoint.web.test.WebEndpointTest
;
import
org.springframework.boot.logging.LogLevel
;
import
org.springframework.boot.logging.LogLevel
;
import
org.springframework.boot.logging.LoggerConfiguration
;
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.logging.LoggingSystem
;
import
org.springframework.context.ConfigurableApplicationContext
;
import
org.springframework.context.ConfigurableApplicationContext
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Bean
;
...
@@ -54,6 +57,7 @@ import static org.mockito.Mockito.verifyZeroInteractions;
...
@@ -54,6 +57,7 @@ import static org.mockito.Mockito.verifyZeroInteractions;
* @author Stephane Nicoll
* @author Stephane Nicoll
* @author Andy Wilkinson
* @author Andy Wilkinson
* @author HaiTao Zhang
* @author HaiTao Zhang
* @author Madhura Bhave
*/
*/
class
LoggersEndpointWebIntegrationTests
{
class
LoggersEndpointWebIntegrationTests
{
...
@@ -61,41 +65,21 @@ class LoggersEndpointWebIntegrationTests {
...
@@ -61,41 +65,21 @@ class LoggersEndpointWebIntegrationTests {
private
LoggingSystem
loggingSystem
;
private
LoggingSystem
loggingSystem
;
private
LoggingGroups
loggingGroups
;
private
LoggerGroups
loggerGroups
;
private
ObjectProvider
<
LoggingGroups
>
loggingGroupsObjectProvider
;
@BeforeEach
@BeforeEach
@AfterEach
@AfterEach
void
resetMocks
(
ConfigurableApplicationContext
context
,
WebTestClient
client
)
{
void
resetMocks
(
ConfigurableApplicationContext
context
,
WebTestClient
client
)
{
this
.
client
=
client
;
this
.
client
=
client
;
this
.
loggingSystem
=
context
.
getBean
(
LoggingSystem
.
class
);
this
.
loggingSystem
=
context
.
getBean
(
LoggingSystem
.
class
);
this
.
loggingGroups
=
context
.
getBean
(
LoggingGroups
.
class
);
this
.
loggerGroups
=
context
.
getBean
(
LoggerGroups
.
class
);
this
.
loggingGroupsObjectProvider
=
context
.
getBean
(
ObjectProvider
.
class
);
Mockito
.
reset
(
this
.
loggingSystem
);
Mockito
.
reset
(
this
.
loggingSystem
);
Mockito
.
reset
(
this
.
loggingGroups
);
given
(
this
.
loggingSystem
.
getSupportedLogLevels
()).
willReturn
(
EnumSet
.
allOf
(
LogLevel
.
class
));
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
@WebEndpointTest
void
getLoggerShouldReturnAllLoggerConfigurationsWithLoggerGroups
()
{
void
getLoggerShouldReturnAllLoggerConfigurationsWithLoggerGroups
()
{
given
(
this
.
loggingGroups
.
getLoggerGroupNames
()).
willReturn
(
Collections
.
singleton
(
"test"
));
setLogLevelToDebug
(
"test"
);
given
(
this
.
loggingGroups
.
getLoggerGroup
(
"test"
)).
willReturn
(
Arrays
.
asList
(
"test.member1"
,
"test.member2"
));
given
(
this
.
loggingGroups
.
getLoggerGroupConfiguredLevel
(
"test"
)).
willReturn
(
LogLevel
.
DEBUG
);
given
(
this
.
loggingSystem
.
getLoggerConfigurations
())
given
(
this
.
loggingSystem
.
getLoggerConfigurations
())
.
willReturn
(
Collections
.
singletonList
(
new
LoggerConfiguration
(
"ROOT"
,
null
,
LogLevel
.
DEBUG
)));
.
willReturn
(
Collections
.
singletonList
(
new
LoggerConfiguration
(
"ROOT"
,
null
,
LogLevel
.
DEBUG
)));
this
.
client
.
get
().
uri
(
"/actuator/loggers"
).
exchange
().
expectStatus
().
isOk
().
expectBody
().
jsonPath
(
"$.length()"
)
this
.
client
.
get
().
uri
(
"/actuator/loggers"
).
exchange
().
expectStatus
().
isOk
().
expectBody
().
jsonPath
(
"$.length()"
)
...
@@ -103,15 +87,13 @@ class LoggersEndpointWebIntegrationTests {
...
@@ -103,15 +87,13 @@ class LoggersEndpointWebIntegrationTests {
.
isEqualTo
(
jsonArrayOf
(
"OFF"
,
"FATAL"
,
"ERROR"
,
"WARN"
,
"INFO"
,
"DEBUG"
,
"TRACE"
))
.
isEqualTo
(
jsonArrayOf
(
"OFF"
,
"FATAL"
,
"ERROR"
,
"WARN"
,
"INFO"
,
"DEBUG"
,
"TRACE"
))
.
jsonPath
(
"loggers.length()"
).
isEqualTo
(
1
).
jsonPath
(
"loggers.ROOT.length()"
).
isEqualTo
(
2
)
.
jsonPath
(
"loggers.length()"
).
isEqualTo
(
1
).
jsonPath
(
"loggers.ROOT.length()"
).
isEqualTo
(
2
)
.
jsonPath
(
"loggers.ROOT.configuredLevel"
).
isEqualTo
(
null
).
jsonPath
(
"loggers.ROOT.effectiveLevel"
)
.
jsonPath
(
"loggers.ROOT.configuredLevel"
).
isEqualTo
(
null
).
jsonPath
(
"loggers.ROOT.effectiveLevel"
)
.
isEqualTo
(
"DEBUG"
).
jsonPath
(
"groups.length()"
).
isEqualTo
(
1
).
jsonPath
(
"groups.test.length()"
)
.
isEqualTo
(
"DEBUG"
).
jsonPath
(
"groups.length()"
).
isEqualTo
(
2
).
jsonPath
(
"groups.test.configuredLevel"
)
.
isEqualTo
(
2
).
jsonPath
(
"groups.test.configuredLevel"
).
isEqualTo
(
"DEBUG"
)
.
isEqualTo
(
"DEBUG"
);
.
jsonPath
(
"groups.test.members.length()"
).
isEqualTo
(
2
).
jsonPath
(
"groups.test.members"
)
.
value
(
IsIterableContainingInAnyOrder
.
containsInAnyOrder
(
"test.member1"
,
"test.member2"
));
}
}
@WebEndpointTest
@WebEndpointTest
void
getLoggerShouldReturnLogLevels
()
{
void
getLoggerShouldReturnLogLevels
()
{
given
(
this
.
loggingGroups
.
isGroup
(
"ROOT"
)).
willReturn
(
false
);
setLogLevelToDebug
(
"test"
);
given
(
this
.
loggingSystem
.
getLoggerConfiguration
(
"ROOT"
))
given
(
this
.
loggingSystem
.
getLoggerConfiguration
(
"ROOT"
))
.
willReturn
(
new
LoggerConfiguration
(
"ROOT"
,
null
,
LogLevel
.
DEBUG
));
.
willReturn
(
new
LoggerConfiguration
(
"ROOT"
,
null
,
LogLevel
.
DEBUG
));
this
.
client
.
get
().
uri
(
"/actuator/loggers/ROOT"
).
exchange
().
expectStatus
().
isOk
().
expectBody
()
this
.
client
.
get
().
uri
(
"/actuator/loggers/ROOT"
).
exchange
().
expectStatus
().
isOk
().
expectBody
()
...
@@ -126,9 +108,7 @@ class LoggersEndpointWebIntegrationTests {
...
@@ -126,9 +108,7 @@ class LoggersEndpointWebIntegrationTests {
@WebEndpointTest
@WebEndpointTest
void
getLoggerGroupShouldReturnConfiguredLogLevelAndMembers
()
{
void
getLoggerGroupShouldReturnConfiguredLogLevelAndMembers
()
{
given
(
this
.
loggingGroups
.
isGroup
(
"test"
)).
willReturn
(
true
);
setLogLevelToDebug
(
"test"
);
given
(
this
.
loggingGroups
.
getLoggerGroupConfiguredLevel
(
"test"
)).
willReturn
(
LogLevel
.
DEBUG
);
given
(
this
.
loggingGroups
.
getLoggerGroup
(
"test"
)).
willReturn
(
Arrays
.
asList
(
"test.member1"
,
"test.member2"
));
this
.
client
.
get
().
uri
(
"actuator/loggers/test"
).
exchange
().
expectStatus
().
isOk
().
expectBody
()
this
.
client
.
get
().
uri
(
"actuator/loggers/test"
).
exchange
().
expectStatus
().
isOk
().
expectBody
()
.
jsonPath
(
"$.length()"
).
isEqualTo
(
2
).
jsonPath
(
"members"
)
.
jsonPath
(
"$.length()"
).
isEqualTo
(
2
).
jsonPath
(
"members"
)
.
value
(
IsIterableContainingInAnyOrder
.
containsInAnyOrder
(
"test.member1"
,
"test.member2"
))
.
value
(
IsIterableContainingInAnyOrder
.
containsInAnyOrder
(
"test.member1"
,
"test.member2"
))
...
@@ -137,7 +117,6 @@ class LoggersEndpointWebIntegrationTests {
...
@@ -137,7 +117,6 @@ class LoggersEndpointWebIntegrationTests {
@WebEndpointTest
@WebEndpointTest
void
setLoggerUsingApplicationJsonShouldSetLogLevel
()
{
void
setLoggerUsingApplicationJsonShouldSetLogLevel
()
{
given
(
this
.
loggingGroups
.
isGroup
(
"ROOT"
)).
willReturn
(
false
);
this
.
client
.
post
().
uri
(
"/actuator/loggers/ROOT"
).
contentType
(
MediaType
.
APPLICATION_JSON
)
this
.
client
.
post
().
uri
(
"/actuator/loggers/ROOT"
).
contentType
(
MediaType
.
APPLICATION_JSON
)
.
body
(
Collections
.
singletonMap
(
"configuredLevel"
,
"debug"
)).
exchange
().
expectStatus
().
isNoContent
();
.
body
(
Collections
.
singletonMap
(
"configuredLevel"
,
"debug"
)).
exchange
().
expectStatus
().
isNoContent
();
verify
(
this
.
loggingSystem
).
setLogLevel
(
"ROOT"
,
LogLevel
.
DEBUG
);
verify
(
this
.
loggingSystem
).
setLogLevel
(
"ROOT"
,
LogLevel
.
DEBUG
);
...
@@ -145,7 +124,6 @@ class LoggersEndpointWebIntegrationTests {
...
@@ -145,7 +124,6 @@ class LoggersEndpointWebIntegrationTests {
@WebEndpointTest
@WebEndpointTest
void
setLoggerUsingActuatorV2JsonShouldSetLogLevel
()
{
void
setLoggerUsingActuatorV2JsonShouldSetLogLevel
()
{
given
(
this
.
loggingGroups
.
isGroup
(
"ROOT"
)).
willReturn
(
false
);
this
.
client
.
post
().
uri
(
"/actuator/loggers/ROOT"
)
this
.
client
.
post
().
uri
(
"/actuator/loggers/ROOT"
)
.
contentType
(
MediaType
.
parseMediaType
(
ActuatorMediaType
.
V2_JSON
))
.
contentType
(
MediaType
.
parseMediaType
(
ActuatorMediaType
.
V2_JSON
))
.
body
(
Collections
.
singletonMap
(
"configuredLevel"
,
"debug"
)).
exchange
().
expectStatus
().
isNoContent
();
.
body
(
Collections
.
singletonMap
(
"configuredLevel"
,
"debug"
)).
exchange
().
expectStatus
().
isNoContent
();
...
@@ -154,21 +132,19 @@ class LoggersEndpointWebIntegrationTests {
...
@@ -154,21 +132,19 @@ class LoggersEndpointWebIntegrationTests {
@WebEndpointTest
@WebEndpointTest
void
setLoggerGroupUsingActuatorV2JsonShouldSetLogLevel
()
{
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"
)
this
.
client
.
post
().
uri
(
"/actuator/loggers/test"
)
.
contentType
(
MediaType
.
parseMediaType
(
ActuatorMediaType
.
V2_JSON
))
.
contentType
(
MediaType
.
parseMediaType
(
ActuatorMediaType
.
V2_JSON
))
.
body
(
Collections
.
singletonMap
(
"configuredLevel"
,
"debug"
)).
exchange
().
expectStatus
().
isNoContent
();
.
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
@WebEndpointTest
void
setLoggerGroupUsingApplicationJsonShouldSetLogLevel
()
{
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
)
this
.
client
.
post
().
uri
(
"/actuator/loggers/test"
).
contentType
(
MediaType
.
APPLICATION_JSON
)
.
body
(
Collections
.
singletonMap
(
"configuredLevel"
,
"debug"
)).
exchange
().
expectStatus
().
isNoContent
();
.
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
@WebEndpointTest
...
@@ -180,7 +156,6 @@ class LoggersEndpointWebIntegrationTests {
...
@@ -180,7 +156,6 @@ class LoggersEndpointWebIntegrationTests {
@WebEndpointTest
@WebEndpointTest
void
setLoggerWithNullLogLevel
()
{
void
setLoggerWithNullLogLevel
()
{
given
(
this
.
loggingGroups
.
isGroup
(
"ROOT"
)).
willReturn
(
false
);
this
.
client
.
post
().
uri
(
"/actuator/loggers/ROOT"
)
this
.
client
.
post
().
uri
(
"/actuator/loggers/ROOT"
)
.
contentType
(
MediaType
.
parseMediaType
(
ActuatorMediaType
.
V2_JSON
))
.
contentType
(
MediaType
.
parseMediaType
(
ActuatorMediaType
.
V2_JSON
))
.
body
(
Collections
.
singletonMap
(
"configuredLevel"
,
null
)).
exchange
().
expectStatus
().
isNoContent
();
.
body
(
Collections
.
singletonMap
(
"configuredLevel"
,
null
)).
exchange
().
expectStatus
().
isNoContent
();
...
@@ -189,7 +164,6 @@ class LoggersEndpointWebIntegrationTests {
...
@@ -189,7 +164,6 @@ class LoggersEndpointWebIntegrationTests {
@WebEndpointTest
@WebEndpointTest
void
setLoggerWithNoLogLevel
()
{
void
setLoggerWithNoLogLevel
()
{
given
(
this
.
loggingGroups
.
isGroup
(
"ROOT"
)).
willReturn
(
false
);
this
.
client
.
post
().
uri
(
"/actuator/loggers/ROOT"
)
this
.
client
.
post
().
uri
(
"/actuator/loggers/ROOT"
)
.
contentType
(
MediaType
.
parseMediaType
(
ActuatorMediaType
.
V2_JSON
)).
body
(
Collections
.
emptyMap
())
.
contentType
(
MediaType
.
parseMediaType
(
ActuatorMediaType
.
V2_JSON
)).
body
(
Collections
.
emptyMap
())
.
exchange
().
expectStatus
().
isNoContent
();
.
exchange
().
expectStatus
().
isNoContent
();
...
@@ -198,22 +172,20 @@ class LoggersEndpointWebIntegrationTests {
...
@@ -198,22 +172,20 @@ class LoggersEndpointWebIntegrationTests {
@WebEndpointTest
@WebEndpointTest
void
setLoggerGroupWithNullLogLevel
()
{
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"
)
this
.
client
.
post
().
uri
(
"/actuator/loggers/test"
)
.
contentType
(
MediaType
.
parseMediaType
(
ActuatorMediaType
.
V2_JSON
))
.
contentType
(
MediaType
.
parseMediaType
(
ActuatorMediaType
.
V2_JSON
))
.
body
(
Collections
.
singletonMap
(
"configuredLevel"
,
null
)).
exchange
().
expectStatus
().
isNoContent
();
.
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
@WebEndpointTest
void
setLoggerGroupWithNoLogLevel
()
{
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"
)
this
.
client
.
post
().
uri
(
"/actuator/loggers/test"
)
.
contentType
(
MediaType
.
parseMediaType
(
ActuatorMediaType
.
V2_JSON
)).
body
(
Collections
.
emptyMap
())
.
contentType
(
MediaType
.
parseMediaType
(
ActuatorMediaType
.
V2_JSON
)).
body
(
Collections
.
emptyMap
())
.
exchange
().
expectStatus
().
isNoContent
();
.
exchange
().
expectStatus
().
isNoContent
();
verify
(
this
.
loggingGroups
).
setLoggerGroupLevel
(
"test"
,
null
);
verify
(
this
.
loggingSystem
).
setLogLevel
(
"test.member1"
,
null
);
verify
(
this
.
loggingSystem
).
setLogLevel
(
"test.member2"
,
null
);
}
}
@WebEndpointTest
@WebEndpointTest
...
@@ -227,12 +199,15 @@ class LoggersEndpointWebIntegrationTests {
...
@@ -227,12 +199,15 @@ class LoggersEndpointWebIntegrationTests {
@WebEndpointTest
@WebEndpointTest
void
logLevelForLoggerGroupWithNameThatCouldBeMistakenForAPathExtension
()
{
void
logLevelForLoggerGroupWithNameThatCouldBeMistakenForAPathExtension
()
{
given
(
this
.
loggingGroups
.
isGroup
(
"com.png"
)).
willReturn
(
true
);
setLogLevelToDebug
(
"group.png"
);
given
(
this
.
loggingGroups
.
getLoggerGroupConfiguredLevel
(
"com.png"
)).
willReturn
(
LogLevel
.
DEBUG
);
this
.
client
.
get
().
uri
(
"/actuator/loggers/group.png"
).
exchange
().
expectStatus
().
isOk
().
expectBody
()
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
()
.
jsonPath
(
"$.length()"
).
isEqualTo
(
2
).
jsonPath
(
"configuredLevel"
).
isEqualTo
(
"DEBUG"
).
jsonPath
(
"members"
)
.
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
)
{
private
JSONArray
jsonArrayOf
(
Object
...
entries
)
{
...
@@ -250,18 +225,20 @@ class LoggersEndpointWebIntegrationTests {
...
@@ -250,18 +225,20 @@ class LoggersEndpointWebIntegrationTests {
}
}
@Bean
@Bean
ObjectProvider
<
LoggingGroups
>
loggingGroupsObjectProvider
()
{
LoggerGroups
loggingGroups
()
{
return
mock
(
ObjectProvider
.
class
);
return
getLoggerGroups
(
);
}
}
@Bean
private
LoggerGroups
getLoggerGroups
()
{
LoggingGroups
loggingGroups
()
{
Map
<
String
,
List
<
String
>>
groups
=
new
LinkedHashMap
<>();
return
mock
(
LoggingGroups
.
class
);
groups
.
put
(
"test"
,
Arrays
.
asList
(
"test.member1"
,
"test.member2"
));
groups
.
put
(
"group.png"
,
Arrays
.
asList
(
"png.member1"
,
"png.member2"
));
return
new
LoggerGroups
(
groups
);
}
}
@Bean
@Bean
LoggersEndpoint
endpoint
(
LoggingSystem
loggingSystem
,
LoggersEndpoint
endpoint
(
LoggingSystem
loggingSystem
,
ObjectProvider
<
Logg
ing
Groups
>
loggingGroupsObjectProvider
)
{
ObjectProvider
<
Logg
er
Groups
>
loggingGroupsObjectProvider
)
{
return
new
LoggersEndpoint
(
loggingSystem
,
loggingGroupsObjectProvider
.
getIfAvailable
());
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 @@
...
@@ -16,12 +16,11 @@
package
org
.
springframework
.
boot
.
context
.
logging
;
package
org
.
springframework
.
boot
.
context
.
logging
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.Collections
;
import
java.util.LinkedHashMap
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Map
;
import
java.util.concurrent.atomic.AtomicBoolean
;
import
java.util.concurrent.atomic.AtomicBoolean
;
import
java.util.function.BiConsumer
;
import
org.apache.commons.logging.Log
;
import
org.apache.commons.logging.Log
;
import
org.apache.commons.logging.LogFactory
;
import
org.apache.commons.logging.LogFactory
;
...
@@ -37,7 +36,8 @@ import org.springframework.boot.context.properties.bind.Binder;
...
@@ -37,7 +36,8 @@ import org.springframework.boot.context.properties.bind.Binder;
import
org.springframework.boot.context.properties.source.ConfigurationPropertyName
;
import
org.springframework.boot.context.properties.source.ConfigurationPropertyName
;
import
org.springframework.boot.logging.LogFile
;
import
org.springframework.boot.logging.LogFile
;
import
org.springframework.boot.logging.LogLevel
;
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.LoggingInitializationContext
;
import
org.springframework.boot.logging.LoggingSystem
;
import
org.springframework.boot.logging.LoggingSystem
;
import
org.springframework.boot.logging.LoggingSystemProperties
;
import
org.springframework.boot.logging.LoggingSystemProperties
;
...
@@ -52,7 +52,6 @@ import org.springframework.core.env.ConfigurableEnvironment;
...
@@ -52,7 +52,6 @@ import org.springframework.core.env.ConfigurableEnvironment;
import
org.springframework.core.env.Environment
;
import
org.springframework.core.env.Environment
;
import
org.springframework.util.LinkedMultiValueMap
;
import
org.springframework.util.LinkedMultiValueMap
;
import
org.springframework.util.MultiValueMap
;
import
org.springframework.util.MultiValueMap
;
import
org.springframework.util.ObjectUtils
;
import
org.springframework.util.ResourceUtils
;
import
org.springframework.util.ResourceUtils
;
import
org.springframework.util.StringUtils
;
import
org.springframework.util.StringUtils
;
...
@@ -85,6 +84,7 @@ import org.springframework.util.StringUtils;
...
@@ -85,6 +84,7 @@ import org.springframework.util.StringUtils;
* @author Phillip Webb
* @author Phillip Webb
* @author Andy Wilkinson
* @author Andy Wilkinson
* @author Madhura Bhave
* @author Madhura Bhave
* @author HaiTao Zhang
* @since 2.0.0
* @since 2.0.0
* @see LoggingSystem#get(ClassLoader)
* @see LoggingSystem#get(ClassLoader)
*/
*/
...
@@ -97,8 +97,8 @@ public class LoggingApplicationListener implements GenericApplicationListener {
...
@@ -97,8 +97,8 @@ public class LoggingApplicationListener implements GenericApplicationListener {
private
static
final
Bindable
<
Map
<
String
,
LogLevel
>>
STRING_LOGLEVEL_MAP
=
Bindable
.
mapOf
(
String
.
class
,
private
static
final
Bindable
<
Map
<
String
,
LogLevel
>>
STRING_LOGLEVEL_MAP
=
Bindable
.
mapOf
(
String
.
class
,
LogLevel
.
class
);
LogLevel
.
class
);
private
static
final
Bindable
<
Map
<
String
,
String
[]>>
STRING_STRINGS_MAP
=
Bindable
.
mapOf
(
String
.
class
,
private
static
final
Bindable
<
Map
<
String
,
List
<
String
>>>
STRING_STRINGS_MAP
=
Bindable
String
[].
class
);
.
of
(
ResolvableType
.
forClassWithGenerics
(
MultiValueMap
.
class
,
String
.
class
,
String
.
class
).
asMap
()
);
/**
/**
* The default order for the LoggingApplicationListener.
* The default order for the LoggingApplicationListener.
...
@@ -129,9 +129,10 @@ public class LoggingApplicationListener implements GenericApplicationListener {
...
@@ -129,9 +129,10 @@ public class LoggingApplicationListener implements GenericApplicationListener {
public
static
final
String
LOGFILE_BEAN_NAME
=
"springBootLogFile"
;
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
;
private
static
final
Map
<
String
,
List
<
String
>>
DEFAULT_GROUP_LOGGERS
;
static
{
static
{
...
@@ -147,7 +148,7 @@ public class LoggingApplicationListener implements GenericApplicationListener {
...
@@ -147,7 +148,7 @@ public class LoggingApplicationListener implements GenericApplicationListener {
DEFAULT_GROUP_LOGGERS
=
Collections
.
unmodifiableMap
(
loggers
);
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
{
static
{
MultiValueMap
<
LogLevel
,
String
>
loggers
=
new
LinkedMultiValueMap
<>();
MultiValueMap
<
LogLevel
,
String
>
loggers
=
new
LinkedMultiValueMap
<>();
loggers
.
add
(
LogLevel
.
DEBUG
,
"sql"
);
loggers
.
add
(
LogLevel
.
DEBUG
,
"sql"
);
...
@@ -158,7 +159,7 @@ public class LoggingApplicationListener implements GenericApplicationListener {
...
@@ -158,7 +159,7 @@ public class LoggingApplicationListener implements GenericApplicationListener {
loggers
.
add
(
LogLevel
.
TRACE
,
"org.apache.catalina"
);
loggers
.
add
(
LogLevel
.
TRACE
,
"org.apache.catalina"
);
loggers
.
add
(
LogLevel
.
TRACE
,
"org.eclipse.jetty"
);
loggers
.
add
(
LogLevel
.
TRACE
,
"org.eclipse.jetty"
);
loggers
.
add
(
LogLevel
.
TRACE
,
"org.hibernate.tool.hbm2ddl"
);
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
,
private
static
final
Class
<?>[]
EVENT_TYPES
=
{
ApplicationStartingEvent
.
class
,
...
@@ -173,10 +174,10 @@ public class LoggingApplicationListener implements GenericApplicationListener {
...
@@ -173,10 +174,10 @@ public class LoggingApplicationListener implements GenericApplicationListener {
private
LoggingSystem
loggingSystem
;
private
LoggingSystem
loggingSystem
;
private
LoggingGroups
loggingGroups
;
private
LogFile
logFile
;
private
LogFile
logFile
;
private
LoggerGroups
loggerGroups
;
private
int
order
=
DEFAULT_ORDER
;
private
int
order
=
DEFAULT_ORDER
;
private
boolean
parseArgs
=
true
;
private
boolean
parseArgs
=
true
;
...
@@ -244,8 +245,8 @@ public class LoggingApplicationListener implements GenericApplicationListener {
...
@@ -244,8 +245,8 @@ public class LoggingApplicationListener implements GenericApplicationListener {
if
(
this
.
logFile
!=
null
&&
!
beanFactory
.
containsBean
(
LOGFILE_BEAN_NAME
))
{
if
(
this
.
logFile
!=
null
&&
!
beanFactory
.
containsBean
(
LOGFILE_BEAN_NAME
))
{
beanFactory
.
registerSingleton
(
LOGFILE_BEAN_NAME
,
this
.
logFile
);
beanFactory
.
registerSingleton
(
LOGFILE_BEAN_NAME
,
this
.
logFile
);
}
}
if
(
this
.
logg
ingGroups
!=
null
&&
!
beanFactory
.
containsBean
(
LOGGING
_GROUPS_BEAN_NAME
))
{
if
(
this
.
logg
erGroups
!=
null
&&
!
beanFactory
.
containsBean
(
LOGGER
_GROUPS_BEAN_NAME
))
{
beanFactory
.
registerSingleton
(
LOGG
ING_GROUPS_BEAN_NAME
,
this
.
logging
Groups
);
beanFactory
.
registerSingleton
(
LOGG
ER_GROUPS_BEAN_NAME
,
this
.
logger
Groups
);
}
}
}
}
...
@@ -269,11 +270,11 @@ public class LoggingApplicationListener implements GenericApplicationListener {
...
@@ -269,11 +270,11 @@ public class LoggingApplicationListener implements GenericApplicationListener {
*/
*/
protected
void
initialize
(
ConfigurableEnvironment
environment
,
ClassLoader
classLoader
)
{
protected
void
initialize
(
ConfigurableEnvironment
environment
,
ClassLoader
classLoader
)
{
new
LoggingSystemProperties
(
environment
).
apply
();
new
LoggingSystemProperties
(
environment
).
apply
();
this
.
loggingGroups
=
new
LoggingGroups
(
this
.
loggingSystem
);
this
.
logFile
=
LogFile
.
get
(
environment
);
this
.
logFile
=
LogFile
.
get
(
environment
);
if
(
this
.
logFile
!=
null
)
{
if
(
this
.
logFile
!=
null
)
{
this
.
logFile
.
applyToSystemProperties
();
this
.
logFile
.
applyToSystemProperties
();
}
}
this
.
loggerGroups
=
new
LoggerGroups
(
DEFAULT_GROUP_LOGGERS
);
initializeEarlyLoggingLevel
(
environment
);
initializeEarlyLoggingLevel
(
environment
);
initializeSystem
(
environment
,
this
.
loggingSystem
,
this
.
logFile
);
initializeSystem
(
environment
,
this
.
loggingSystem
,
this
.
logFile
);
initializeFinalLoggingLevels
(
environment
,
this
.
loggingSystem
);
initializeFinalLoggingLevels
(
environment
,
this
.
loggingSystem
);
...
@@ -321,70 +322,95 @@ public class LoggingApplicationListener implements GenericApplicationListener {
...
@@ -321,70 +322,95 @@ public class LoggingApplicationListener implements GenericApplicationListener {
}
}
private
void
initializeFinalLoggingLevels
(
ConfigurableEnvironment
environment
,
LoggingSystem
system
)
{
private
void
initializeFinalLoggingLevels
(
ConfigurableEnvironment
environment
,
LoggingSystem
system
)
{
bindLoggerGroups
(
environment
);
if
(
this
.
springBootLogging
!=
null
)
{
if
(
this
.
springBootLogging
!=
null
)
{
initializeLogLevel
(
system
,
this
.
springBootLogging
);
initializeLogLevel
(
system
,
this
.
springBootLogging
);
}
}
setLogLevels
(
system
,
environment
);
setLogLevels
(
system
,
environment
);
}
}
protected
void
initializeLogLevel
(
LoggingSystem
system
,
LogLevel
level
)
{
private
void
bindLoggerGroups
(
ConfigurableEnvironment
environment
)
{
LOG_LEVEL_LOGGERS
.
getOrDefault
(
level
,
Collections
.
emptyList
())
if
(
this
.
loggerGroups
!=
null
)
{
.
forEach
((
logger
)
->
initializeLogLevel
(
system
,
level
,
logger
));
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
);
* Initialize loggers based on the {@link #setSpringBootLogging(LogLevel)
if
(
groupLoggers
==
null
)
{
* springBootLogging} setting.
system
.
setLogLevel
(
logger
,
level
);
* @param system the logging system
return
;
* @param springBootLogging the spring boot logging level requested
}
* @deprecated since 2.2.0 in favor of
this
.
loggingGroups
.
setLoggerGroup
(
logger
,
groupLoggers
);
* {@link #initializeSpringBootLogging(LoggingSystem, LogLevel)}
this
.
loggingGroups
.
setLoggerGroupLevel
(
logger
,
level
);
*/
@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
)
{
protected
void
setLogLevels
(
LoggingSystem
system
,
Environment
environment
)
{
if
(
!(
environment
instanceof
ConfigurableEnvironment
)
)
{
if
(
environment
instanceof
ConfigurableEnvironment
)
{
return
;
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
<>();
* Set logging levels based on relevant {@link Environment} properties.
DEFAULT_GROUP_LOGGERS
.
forEach
((
name
,
loggers
)
->
groups
.
put
(
name
,
StringUtils
.
toStringArray
(
loggers
)));
* @param system the logging system
return
groups
;
* @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
)
{
private
void
configureLogLevel
(
String
name
,
LogLevel
level
,
BiConsumer
<
String
,
LogLevel
>
configurer
)
{
try
{
if
(
this
.
loggerGroups
!=
null
)
{
this
.
loggingGroups
.
setLoggerGroup
(
groupName
,
Arrays
.
asList
(
names
)
);
LoggerGroup
group
=
this
.
loggerGroups
.
get
(
name
);
this
.
loggingGroups
.
setLoggerGroupLevel
(
groupName
,
level
);
if
(
group
!=
null
&&
group
.
hasMembers
())
{
}
group
.
configureLogLevel
(
level
,
configurer
);
catch
(
RuntimeException
ex
)
{
return
;
this
.
logger
.
error
(
"Cannot set level '"
+
level
+
"' for '"
+
groupName
+
"'"
);
}
}
}
configurer
.
accept
(
name
,
level
);
}
}
private
void
setLogLevel
(
LoggingSystem
system
,
String
name
,
LogLevel
level
)
{
private
BiConsumer
<
String
,
LogLevel
>
getLogLevelConfigurer
(
LoggingSystem
system
)
{
try
{
return
(
name
,
level
)
->
{
name
=
name
.
equalsIgnoreCase
(
LoggingSystem
.
ROOT_LOGGER_NAME
)
?
null
:
name
;
try
{
system
.
setLogLevel
(
name
,
level
);
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
+
"'"
);
catch
(
RuntimeException
ex
)
{
}
this
.
logger
.
error
(
"Cannot set level '"
+
level
+
"' for '"
+
name
+
"'"
);
}
};
}
}
private
void
registerShutdownHookIfNecessary
(
Environment
environment
,
LoggingSystem
loggingSystem
)
{
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 @@
...
@@ -16,29 +16,50 @@
package
org
.
springframework
.
boot
.
logging
;
package
org
.
springframework
.
boot
.
logging
;
import
java.util.Arrays
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
org.junit.jupiter.api.Test
;
import
java.util.List
;
import
java.util.function.BiConsumer
;
import
static
org
.
mockito
.
Mockito
.
mock
;
import
static
org
.
mockito
.
Mockito
.
verify
;
/**
/**
*
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
public
void
configureLogLevel
(
LogLevel
level
,
BiConsumer
<
String
,
LogLevel
>
configurer
)
{
void
setLoggerGroupWithTheConfiguredLevelToAllMembers
()
{
this
.
configuredLevel
=
level
;
LoggingGroups
loggingGroups
=
new
LoggingGroups
(
this
.
loggingSystem
);
this
.
members
.
forEach
((
name
)
->
configurer
.
accept
(
name
,
level
));
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
);
}
}
}
}
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;
...
@@ -50,6 +50,7 @@ import org.springframework.boot.logging.AbstractLoggingSystem;
import
org.springframework.boot.logging.LogFile
;
import
org.springframework.boot.logging.LogFile
;
import
org.springframework.boot.logging.LogLevel
;
import
org.springframework.boot.logging.LogLevel
;
import
org.springframework.boot.logging.LoggerConfiguration
;
import
org.springframework.boot.logging.LoggerConfiguration
;
import
org.springframework.boot.logging.LoggerGroups
;
import
org.springframework.boot.logging.LoggingInitializationContext
;
import
org.springframework.boot.logging.LoggingInitializationContext
;
import
org.springframework.boot.logging.LoggingSystem
;
import
org.springframework.boot.logging.LoggingSystem
;
import
org.springframework.boot.logging.LoggingSystemProperties
;
import
org.springframework.boot.logging.LoggingSystemProperties
;
...
@@ -284,6 +285,8 @@ class LoggingApplicationListenerTests {
...
@@ -284,6 +285,8 @@ class LoggingApplicationListenerTests {
this
.
loggerContext
.
getLogger
(
"org.hibernate.SQL"
).
debug
(
"testdebugsqlgroup"
);
this
.
loggerContext
.
getLogger
(
"org.hibernate.SQL"
).
debug
(
"testdebugsqlgroup"
);
assertThat
(
this
.
output
).
contains
(
"testdebugwebgroup"
);
assertThat
(
this
.
output
).
contains
(
"testdebugwebgroup"
);
assertThat
(
this
.
output
).
contains
(
"testdebugsqlgroup"
);
assertThat
(
this
.
output
).
contains
(
"testdebugsqlgroup"
);
LoggerGroups
loggerGroups
=
(
LoggerGroups
)
ReflectionTestUtils
.
getField
(
this
.
initializer
,
"loggerGroups"
);
assertThat
(
loggerGroups
.
get
(
"web"
).
getConfiguredLevel
()).
isEqualTo
(
LogLevel
.
DEBUG
);
}
}
@Test
@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