Skip to content

Commit 746cf62

Browse files
toKrauseMewel
authored andcommitted
MCR-3161 improve startup component logging
1 parent f1a8b3c commit 746cf62

File tree

2 files changed

+87
-11
lines changed

2 files changed

+87
-11
lines changed

mycore-base/src/main/java/org/mycore/common/config/MCRComponent.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,14 +164,21 @@ public String getResourceBase() {
164164
}
165165

166166
/**
167-
* Returns true, if this component is part of MyCoRe
167+
* Returns true, if this component is a MyCore base component
168+
*/
169+
public boolean isMyCoReBaseComponent() {
170+
return type == Type.base;
171+
}
172+
173+
/**
174+
* Returns true, if this component is a MyCoRe component
168175
*/
169176
public boolean isMyCoReComponent() {
170177
return type == Type.base || type == Type.component;
171178
}
172179

173180
/**
174-
* Returns true, if this component is application module
181+
* Returns true, if this component is an application module
175182
*/
176183
public boolean isAppModule() {
177184
return type == Type.module;
@@ -185,6 +192,13 @@ public String getName() {
185192
return name;
186193
}
187194

195+
/**
196+
* The unshortened name for this component.
197+
*/
198+
public String getFullName() {
199+
return artifactId;
200+
}
201+
188202
/**
189203
* Returns the jar file or <code>null</code> if nothing was set.
190204
*

mycore-base/src/main/java/org/mycore/common/events/MCRStartupHandler.java

Lines changed: 71 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,30 @@
1818

1919
package org.mycore.common.events;
2020

21+
import java.io.IOException;
22+
import java.time.ZoneId;
23+
import java.time.format.DateTimeFormatter;
24+
import java.util.List;
25+
import java.util.Locale;
26+
import java.util.jar.JarFile;
2127
import java.util.stream.Stream;
2228

2329
import org.apache.logging.log4j.LogManager;
2430
import org.apache.logging.log4j.Logger;
2531
import org.mycore.common.MCRClassTools;
32+
import org.mycore.common.config.MCRComponent;
2633
import org.mycore.common.config.MCRConfiguration2;
2734
import org.mycore.common.config.MCRConfigurationDirSetup;
2835
import org.mycore.common.config.MCRConfigurationException;
2936
import org.mycore.common.config.MCRRuntimeComponentDetector;
37+
import org.mycore.common.log.MCRTableMessage;
3038
import org.mycore.common.xml.MCRURIResolver;
3139

3240
import jakarta.servlet.ServletContext;
3341

42+
import static jakarta.servlet.ServletContext.ORDERED_LIBS;
43+
import static org.mycore.common.config.MCRRuntimeComponentDetector.ComponentOrder.LOWEST_PRIORITY_FIRST;
44+
3445
/**
3546
* Initializes classes that implement {@link AutoExecutable} interface that are defined via
3647
* <code>MCR.Startup.Class</code> property.
@@ -56,26 +67,71 @@ public static void startUp(ServletContext servletContext) {
5667
isWebApp = servletContext != null;
5768
//initialize ClassLoader here, so it can be used later reliably.
5869
MCRClassTools.updateClassLoader();
70+
5971
ClassLoader resourceClassLoader = MCRClassTools.getClassLoader();
6072
LOGGER.info("The following ClassLoader is used: {}", resourceClassLoader);
61-
LOGGER.info("I have these components for you: {}", MCRRuntimeComponentDetector.getAllComponents());
62-
LOGGER.info("I have these mycore components for you: {}", MCRRuntimeComponentDetector.getMyCoReComponents());
63-
LOGGER.info("I have these app modules for you: {}", MCRRuntimeComponentDetector.getApplicationModules());
73+
74+
MCRTableMessage<MCRComponent> componentTable = new MCRTableMessage<>(
75+
new MCRTableMessage.Column<>("Type", MCRStartupHandler::toType),
76+
new MCRTableMessage.Column<>("Name", MCRComponent::getFullName),
77+
new MCRTableMessage.Column<>("Priority", MCRComponent::getPriority),
78+
new MCRTableMessage.Column<>("Version", MCRStartupHandler::toVersion),
79+
new MCRTableMessage.Column<>("Build time", MCRStartupHandler::toManifestModificationDate),
80+
new MCRTableMessage.Column<>("Location", MCRStartupHandler::toJarFile));
81+
MCRRuntimeComponentDetector.getAllComponents(LOWEST_PRIORITY_FIRST).forEach(componentTable::add);
82+
LOGGER.info(componentTable.logMessage("Detected components:"));
83+
6484
if (servletContext != null) {
65-
LOGGER.info("Library order: {}", servletContext.getAttribute(ServletContext.ORDERED_LIBS));
85+
LOGGER.info("Library order: {}", servletContext.getAttribute(ORDERED_LIBS));
6686
}
6787

68-
MCRConfiguration2.getString("MCR.Startup.Class")
88+
MCRTableMessage<AutoExecutable> executableTable = new MCRTableMessage<>(
89+
new MCRTableMessage.Column<>("Name", AutoExecutable::getName),
90+
new MCRTableMessage.Column<>("Priority", AutoExecutable::getPriority),
91+
new MCRTableMessage.Column<>("Class", executable -> executable.getClass().getName()));
92+
List<AutoExecutable> executables = MCRConfiguration2.getString("MCR.Startup.Class")
6993
.map(MCRConfiguration2::splitValue)
7094
.orElseGet(Stream::empty)
7195
.map(MCRStartupHandler::getAutoExecutable)
72-
//reverse ordering: highest priority first
73-
.sorted((o1, o2) -> Integer.compare(o2.getPriority(), o1.getPriority()))
74-
.forEachOrdered(autoExecutable -> startExecutable(servletContext, autoExecutable));
96+
.sorted()
97+
.peek(executableTable::add)
98+
.toList();
99+
LOGGER.info(executableTable.logMessage("Detected auto executables:"));
100+
executables.forEach(autoExecutable -> startExecutable(servletContext, autoExecutable));
101+
75102
//initialize MCRURIResolver
76103
MCRURIResolver.init(servletContext);
77104
}
78105

106+
private static String toType(MCRComponent component) {
107+
if (component.isMyCoReBaseComponent()) {
108+
return "MyCoRe base component";
109+
} else if (component.isMyCoReComponent()) {
110+
return "MyCoRe component";
111+
} else {
112+
return "Application module";
113+
}
114+
}
115+
116+
private static Object toVersion(MCRComponent component) {
117+
String version = component.getManifestMainAttribute("Implementation-Version");
118+
return version != null ? version : "n/a";
119+
}
120+
121+
private static Object toJarFile(MCRComponent component) {
122+
return component.getJarFile().getAbsolutePath();
123+
}
124+
125+
private static Object toManifestModificationDate(MCRComponent component) {
126+
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
127+
try (JarFile jarFile = new JarFile(component.getJarFile())) {
128+
return formatter.format(jarFile.getEntry("META-INF/MANIFEST.MF").getLastModifiedTime()
129+
.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
130+
} catch (IOException e) {
131+
return "n/a";
132+
}
133+
}
134+
79135
public static boolean isWebApp() {
80136
return isWebApp;
81137
}
@@ -103,7 +159,7 @@ private static AutoExecutable getAutoExecutable(String className) {
103159
}
104160
}
105161

106-
public interface AutoExecutable {
162+
public interface AutoExecutable extends Comparable<AutoExecutable> {
107163
/**
108164
* returns a name to display on start-up.
109165
*/
@@ -118,5 +174,11 @@ public interface AutoExecutable {
118174
* This method get executed by {@link MCRStartupHandler#startUp(ServletContext)}
119175
*/
120176
void startUp(ServletContext servletContext);
177+
178+
@Override
179+
default int compareTo(AutoExecutable other) {
180+
return Integer.compare(other.getPriority(), getPriority());
181+
}
182+
121183
}
122184
}

0 commit comments

Comments
 (0)