From 348b2c28e91f738989b02c1136699b891c8df91b Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 28 Jul 2022 14:13:23 +0100 Subject: [PATCH] Improve logging of changes that trigger a DevTools upload or restart Closes gh-31579 --- .../LocalDevToolsAutoConfiguration.java | 34 +++++++++++++---- .../classpath/ClassPathChangedEvent.java | 37 ++++++++++++++++++- .../client/ClassPathChangeUploader.java | 14 +++---- 3 files changed, 70 insertions(+), 15 deletions(-) diff --git a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/LocalDevToolsAutoConfiguration.java b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/LocalDevToolsAutoConfiguration.java index 51a7a7809b..364e12a127 100644 --- a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/LocalDevToolsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/LocalDevToolsAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2022 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. @@ -20,6 +20,9 @@ import java.io.File; import java.net.URL; import java.util.List; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -44,6 +47,7 @@ import org.springframework.context.annotation.Lazy; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.context.event.GenericApplicationListener; import org.springframework.core.ResolvableType; +import org.springframework.core.log.LogMessage; import org.springframework.util.StringUtils; /** @@ -101,13 +105,9 @@ public class LocalDevToolsAutoConfiguration { } @Bean - ApplicationListener restartingClassPathChangedEventListener( + RestartingClassPathChangeChangedEventListener restartingClassPathChangedEventListener( FileSystemWatcherFactory fileSystemWatcherFactory) { - return (event) -> { - if (event.isRestartRequired()) { - Restarter.getInstance().restart(new FileWatchingFailureHandler(fileSystemWatcherFactory)); - } - }; + return new RestartingClassPathChangeChangedEventListener(fileSystemWatcherFactory); } @Bean @@ -194,4 +194,24 @@ public class LocalDevToolsAutoConfiguration { } + static class RestartingClassPathChangeChangedEventListener implements ApplicationListener { + + private static final Log logger = LogFactory.getLog(RestartingClassPathChangeChangedEventListener.class); + + private final FileSystemWatcherFactory fileSystemWatcherFactory; + + RestartingClassPathChangeChangedEventListener(FileSystemWatcherFactory fileSystemWatcherFactory) { + this.fileSystemWatcherFactory = fileSystemWatcherFactory; + } + + @Override + public void onApplicationEvent(ClassPathChangedEvent event) { + if (event.isRestartRequired()) { + logger.info(LogMessage.format("Restarting due to %s", event.overview())); + Restarter.getInstance().restart(new FileWatchingFailureHandler(this.fileSystemWatcherFactory)); + } + } + + } + } diff --git a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/classpath/ClassPathChangedEvent.java b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/classpath/ClassPathChangedEvent.java index 7d800ba617..982a9e4714 100644 --- a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/classpath/ClassPathChangedEvent.java +++ b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/classpath/ClassPathChangedEvent.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-2022 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. @@ -18,6 +18,8 @@ package org.springframework.boot.devtools.classpath; import java.util.Set; +import org.springframework.boot.devtools.filewatch.ChangedFile; +import org.springframework.boot.devtools.filewatch.ChangedFile.Type; import org.springframework.boot.devtools.filewatch.ChangedFiles; import org.springframework.context.ApplicationEvent; import org.springframework.core.style.ToStringCreator; @@ -71,4 +73,37 @@ public class ClassPathChangedEvent extends ApplicationEvent { .append("restartRequired", this.restartRequired).toString(); } + /** + * Return an overview of the changes that triggered this event. + * @return an overview of the changes + * @since 2.6.11 + */ + public String overview() { + int added = 0; + int deleted = 0; + int modified = 0; + for (ChangedFiles changedFiles : this.changeSet) { + for (ChangedFile changedFile : changedFiles) { + Type type = changedFile.getType(); + if (type == Type.ADD) { + added++; + } + else if (type == Type.DELETE) { + deleted++; + } + else if (type == Type.MODIFY) { + modified++; + } + } + } + int size = added + deleted + modified; + return String.format("%s (%s, %s, %s)", quantityOfUnit(size, "class path change"), + quantityOfUnit(added, "addition"), quantityOfUnit(deleted, "deletion"), + quantityOfUnit(modified, "modification")); + } + + private String quantityOfUnit(int quantity, String unit) { + return quantity + " " + ((quantity != 1) ? unit + "s" : unit); + } + } diff --git a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/client/ClassPathChangeUploader.java b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/client/ClassPathChangeUploader.java index b32a603d3f..2fdf68f206 100644 --- a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/client/ClassPathChangeUploader.java +++ b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/client/ClassPathChangeUploader.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2022 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. @@ -91,14 +91,15 @@ public class ClassPathChangeUploader implements ApplicationListener "Unexpected " + statusCode + " response uploading class files"); - logUpload(classLoaderFiles); return; } catch (SocketException ex) { @@ -128,9 +129,8 @@ public class ClassPathChangeUploader implements ApplicationListener