Skip to content

Commit 348b2c2

Browse files
committed
Improve logging of changes that trigger a DevTools upload or restart
Closes gh-31579
1 parent 9a2ad6d commit 348b2c2

File tree

3 files changed

+70
-15
lines changed

3 files changed

+70
-15
lines changed

spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/LocalDevToolsAutoConfiguration.java

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors.
2+
* Copyright 2012-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -20,6 +20,9 @@
2020
import java.net.URL;
2121
import java.util.List;
2222

23+
import org.apache.commons.logging.Log;
24+
import org.apache.commons.logging.LogFactory;
25+
2326
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
2427
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
2528
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -44,6 +47,7 @@
4447
import org.springframework.context.event.ContextRefreshedEvent;
4548
import org.springframework.context.event.GenericApplicationListener;
4649
import org.springframework.core.ResolvableType;
50+
import org.springframework.core.log.LogMessage;
4751
import org.springframework.util.StringUtils;
4852

4953
/**
@@ -101,13 +105,9 @@ static class RestartConfiguration {
101105
}
102106

103107
@Bean
104-
ApplicationListener<ClassPathChangedEvent> restartingClassPathChangedEventListener(
108+
RestartingClassPathChangeChangedEventListener restartingClassPathChangedEventListener(
105109
FileSystemWatcherFactory fileSystemWatcherFactory) {
106-
return (event) -> {
107-
if (event.isRestartRequired()) {
108-
Restarter.getInstance().restart(new FileWatchingFailureHandler(fileSystemWatcherFactory));
109-
}
110-
};
110+
return new RestartingClassPathChangeChangedEventListener(fileSystemWatcherFactory);
111111
}
112112

113113
@Bean
@@ -194,4 +194,24 @@ public int getOrder() {
194194

195195
}
196196

197+
static class RestartingClassPathChangeChangedEventListener implements ApplicationListener<ClassPathChangedEvent> {
198+
199+
private static final Log logger = LogFactory.getLog(RestartingClassPathChangeChangedEventListener.class);
200+
201+
private final FileSystemWatcherFactory fileSystemWatcherFactory;
202+
203+
RestartingClassPathChangeChangedEventListener(FileSystemWatcherFactory fileSystemWatcherFactory) {
204+
this.fileSystemWatcherFactory = fileSystemWatcherFactory;
205+
}
206+
207+
@Override
208+
public void onApplicationEvent(ClassPathChangedEvent event) {
209+
if (event.isRestartRequired()) {
210+
logger.info(LogMessage.format("Restarting due to %s", event.overview()));
211+
Restarter.getInstance().restart(new FileWatchingFailureHandler(this.fileSystemWatcherFactory));
212+
}
213+
}
214+
215+
}
216+
197217
}

spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/classpath/ClassPathChangedEvent.java

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2021 the original author or authors.
2+
* Copyright 2012-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,6 +18,8 @@
1818

1919
import java.util.Set;
2020

21+
import org.springframework.boot.devtools.filewatch.ChangedFile;
22+
import org.springframework.boot.devtools.filewatch.ChangedFile.Type;
2123
import org.springframework.boot.devtools.filewatch.ChangedFiles;
2224
import org.springframework.context.ApplicationEvent;
2325
import org.springframework.core.style.ToStringCreator;
@@ -71,4 +73,37 @@ public String toString() {
7173
.append("restartRequired", this.restartRequired).toString();
7274
}
7375

76+
/**
77+
* Return an overview of the changes that triggered this event.
78+
* @return an overview of the changes
79+
* @since 2.6.11
80+
*/
81+
public String overview() {
82+
int added = 0;
83+
int deleted = 0;
84+
int modified = 0;
85+
for (ChangedFiles changedFiles : this.changeSet) {
86+
for (ChangedFile changedFile : changedFiles) {
87+
Type type = changedFile.getType();
88+
if (type == Type.ADD) {
89+
added++;
90+
}
91+
else if (type == Type.DELETE) {
92+
deleted++;
93+
}
94+
else if (type == Type.MODIFY) {
95+
modified++;
96+
}
97+
}
98+
}
99+
int size = added + deleted + modified;
100+
return String.format("%s (%s, %s, %s)", quantityOfUnit(size, "class path change"),
101+
quantityOfUnit(added, "addition"), quantityOfUnit(deleted, "deletion"),
102+
quantityOfUnit(modified, "modification"));
103+
}
104+
105+
private String quantityOfUnit(int quantity, String unit) {
106+
return quantity + " " + ((quantity != 1) ? unit + "s" : unit);
107+
}
108+
74109
}

spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/client/ClassPathChangeUploader.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors.
2+
* Copyright 2012-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -91,14 +91,15 @@ public void onApplicationEvent(ClassPathChangedEvent event) {
9191
try {
9292
ClassLoaderFiles classLoaderFiles = getClassLoaderFiles(event);
9393
byte[] bytes = serialize(classLoaderFiles);
94-
performUpload(classLoaderFiles, bytes);
94+
performUpload(classLoaderFiles, bytes, event);
9595
}
9696
catch (IOException ex) {
9797
throw new IllegalStateException(ex);
9898
}
9999
}
100100

101-
private void performUpload(ClassLoaderFiles classLoaderFiles, byte[] bytes) throws IOException {
101+
private void performUpload(ClassLoaderFiles classLoaderFiles, byte[] bytes, ClassPathChangedEvent event)
102+
throws IOException {
102103
try {
103104
while (true) {
104105
try {
@@ -107,11 +108,11 @@ private void performUpload(ClassLoaderFiles classLoaderFiles, byte[] bytes) thro
107108
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
108109
headers.setContentLength(bytes.length);
109110
FileCopyUtils.copy(bytes, request.getBody());
111+
logUpload(event);
110112
ClientHttpResponse response = request.execute();
111113
HttpStatus statusCode = response.getStatusCode();
112114
Assert.state(statusCode == HttpStatus.OK,
113115
() -> "Unexpected " + statusCode + " response uploading class files");
114-
logUpload(classLoaderFiles);
115116
return;
116117
}
117118
catch (SocketException ex) {
@@ -128,9 +129,8 @@ private void performUpload(ClassLoaderFiles classLoaderFiles, byte[] bytes) thro
128129
}
129130
}
130131

131-
private void logUpload(ClassLoaderFiles classLoaderFiles) {
132-
int size = classLoaderFiles.size();
133-
logger.info(LogMessage.format("Uploaded %s class %s", size, (size != 1) ? "resources" : "resource"));
132+
private void logUpload(ClassPathChangedEvent event) {
133+
logger.info(LogMessage.format("Uploading %s", event.overview()));
134134
}
135135

136136
private byte[] serialize(ClassLoaderFiles classLoaderFiles) throws IOException {

0 commit comments

Comments
 (0)