This is an automated email from the ASF dual-hosted git repository.

jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git


The following commit(s) were added to refs/heads/master by this push:
     new c59f01acc Fix bug with RestObject objects.
c59f01acc is described below

commit c59f01accec64b58b8441415dfd4a81a3e43d28d
Author: JamesBognar <james.bog...@salesforce.com>
AuthorDate: Thu Jun 16 11:11:33 2022 -0400

    Fix bug with RestObject objects.
---
 .../java/org/apache/juneau/reflect/ClassInfo.java  |   2 +-
 .../logs/.gitignore                                |   1 +
 .../juneau/examples/rest/RootContentTest.java      |   2 +-
 .../juneau-examples-rest-jetty/logs/.gitignore     |   1 +
 .../juneau-examples-rest-jetty/logs/empty.txt      |   0
 .../examples/rest/springboot/RootResources.java    |   1 -
 .../apache/juneau/examples/rest/RootResources.java |   1 -
 .../juneau/examples/rest/UtilityBeansResource.java | 123 +++++++
 .../org/apache/juneau/microservice/LogConfig.java  | 211 ------------
 .../apache/juneau/microservice/Microservice.java   |  78 +----
 .../microservice/resources/LogEntryFormatter.java  | 272 ---------------
 .../juneau/microservice/resources/LogParser.java   | 234 -------------
 .../microservice/resources/LogsResource.java       | 373 ---------------------
 .../microservice/resources/SampleRootResource.java |   2 +-
 .../java/org/apache/juneau/rest/test/Root.java     |   1 -
 .../rest/test/client/ThirdPartyProxyResource.java  |   1 +
 .../microservice/jetty/JettyMicroservice.java      |   6 -
 .../microservice/jetty/template/RootResources.java |   2 -
 .../springboot/template/RootResources.java         |   3 +-
 .../java/org/apache/juneau/rest/RestContext.java   |   4 +-
 pom.xml                                            |   1 +
 21 files changed, 134 insertions(+), 1185 deletions(-)

diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ClassInfo.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ClassInfo.java
index eb33c0b13..ea7d195e6 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ClassInfo.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ClassInfo.java
@@ -120,7 +120,7 @@ public final class ClassInfo {
         * @return The constructed class info, or <jk>null</jk> if the object 
was <jk>null</jk>.
         */
        public static ClassInfo of(Object o) {
-               return of(o == null ? null : o.getClass());
+               return of(o == null ? null : o instanceof Class ? (Class<?>)o : 
o.getClass());
        }
 
        /**
diff --git a/juneau-examples/juneau-examples-rest-jetty-ftest/logs/.gitignore 
b/juneau-examples/juneau-examples-rest-jetty-ftest/logs/.gitignore
new file mode 100644
index 000000000..bd317cc13
--- /dev/null
+++ b/juneau-examples/juneau-examples-rest-jetty-ftest/logs/.gitignore
@@ -0,0 +1 @@
+/*log*
diff --git 
a/juneau-examples/juneau-examples-rest-jetty-ftest/src/test/java/org/apache/juneau/examples/rest/RootContentTest.java
 
b/juneau-examples/juneau-examples-rest-jetty-ftest/src/test/java/org/apache/juneau/examples/rest/RootContentTest.java
index 9dcd8764c..1383e0493 100644
--- 
a/juneau-examples/juneau-examples-rest-jetty-ftest/src/test/java/org/apache/juneau/examples/rest/RootContentTest.java
+++ 
b/juneau-examples/juneau-examples-rest-jetty-ftest/src/test/java/org/apache/juneau/examples/rest/RootContentTest.java
@@ -95,7 +95,7 @@ public class RootContentTest extends ContentComboTestBase {
                        },
                        {       /* 10 */
                                new ComboInput("HTML-content-octal/msgpack", 
"/", MediaType.MSGPACK,
-                                       "95 82 A4"
+                                       "94 82 A4"
                                )
                        },
                        {       /* 11 */
diff --git a/juneau-examples/juneau-examples-rest-jetty/logs/.gitignore 
b/juneau-examples/juneau-examples-rest-jetty/logs/.gitignore
new file mode 100644
index 000000000..bd317cc13
--- /dev/null
+++ b/juneau-examples/juneau-examples-rest-jetty/logs/.gitignore
@@ -0,0 +1 @@
+/*log*
diff --git a/juneau-examples/juneau-examples-rest-jetty/logs/empty.txt 
b/juneau-examples/juneau-examples-rest-jetty/logs/empty.txt
new file mode 100644
index 000000000..e69de29bb
diff --git 
a/juneau-examples/juneau-examples-rest-springboot/src/main/java/org/apache/juneau/examples/rest/springboot/RootResources.java
 
b/juneau-examples/juneau-examples-rest-springboot/src/main/java/org/apache/juneau/examples/rest/springboot/RootResources.java
index e560cf1d2..dc6f6bd2c 100644
--- 
a/juneau-examples/juneau-examples-rest-springboot/src/main/java/org/apache/juneau/examples/rest/springboot/RootResources.java
+++ 
b/juneau-examples/juneau-examples-rest-springboot/src/main/java/org/apache/juneau/examples/rest/springboot/RootResources.java
@@ -39,7 +39,6 @@ import org.apache.juneau.serializer.annotation.*;
                HelloWorldResource.class,
                DtoExamples.class,
                ConfigResource.class,
-               LogsResource.class,
                ShutdownResource.class
        }
 )
diff --git 
a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RootResources.java
 
b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RootResources.java
index bae630594..de6fb06c3 100644
--- 
a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RootResources.java
+++ 
b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RootResources.java
@@ -39,7 +39,6 @@ import org.apache.juneau.serializer.annotation.*;
                HelloWorldResource.class,
                DtoExamples.class,
                ConfigResource.class,
-               LogsResource.class,
                ShutdownResource.class
        }
 )
diff --git 
a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/UtilityBeansResource.java
 
b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/UtilityBeansResource.java
new file mode 100644
index 000000000..b958bd0eb
--- /dev/null
+++ 
b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/UtilityBeansResource.java
@@ -0,0 +1,123 @@
+// 
***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright 
ownership.  The ASF licenses this file        *
+// * to you 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                
                                              *
+// *                                                                           
                                              *
+// *  http://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.apache.juneau.examples.rest;
+
+import java.util.*;
+
+import org.apache.juneau.annotation.*;
+import org.apache.juneau.examples.parser.*;
+import org.apache.juneau.examples.serializer.*;
+import org.apache.juneau.html.annotation.*;
+import org.apache.juneau.http.annotation.*;
+import org.apache.juneau.http.response.*;
+import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.beans.*;
+import org.apache.juneau.rest.config.*;
+import org.apache.juneau.rest.servlet.*;
+
+import java.awt.image.*;
+import java.net.*;
+
+/**
+ * Sample resource that allows images to be uploaded and retrieved.
+ *
+ * <ul class='seealso'>
+ *     <li class='link'>{@doc jrs.Marshalling REST Marshalling}
+ *     <li class='jc'>{@link ImageSerializer}
+ *     <li class='jc'>{@link ImageParser}
+ *     <li class='extlink'>{@source}
+ * </ul>
+ */
+@Rest(
+       path="/utilitybeans",
+       title="Utility beans examples",
+       description="Examples of utility bean usage."
+)
+@HtmlDocConfig(
+       navlinks="options: ?method=OPTIONS"
+)
+public class UtilityBeansResource extends BasicRestServlet implements 
BasicUniversalConfig {
+
+       private static final long serialVersionUID = 1L;
+
+       @RestGet("/")
+       public ResourceDescriptions getDescriptions() {
+               return ResourceDescriptions
+                       .create()
+                       .append("BeanDescription", "Example of BeanDescription 
bean");
+       }
+
+
+       @RestGet("/BeanDescription")
+       public BeanDescription aBeanDescription() {
+               return BeanDescription.of(AddressBook.class);
+       }
+
+       public static class AddressBook extends LinkedList<Person> {
+
+               public AddressBook init() {
+                       add(
+                               new Person("Bill Clinton", 65,
+                                       new Address("55W. 125th Street", "New 
York", "NY", 10027, true)
+                               )
+                       );
+                       return this;
+               }
+       }
+
+       @Bean(p="street,city,state,zip,isCurrent")
+       public static class Address {
+               public String street;
+               public String city;
+               public String state;
+               public int zip;
+               public boolean isCurrent;
+
+               public Address() {}
+
+               public Address(String street, String city, String state, int 
zip, boolean isCurrent) {
+                       this.street = street;
+                       this.city = city;
+                       this.state = state;
+                       this.zip = zip;
+                       this.isCurrent = isCurrent;
+               }
+               @Override /* Object */
+               public String toString() {
+                       return 
"Address(street="+street+",city="+city+",state="+state+",zip="+zip+",isCurrent="+isCurrent+")";
+               }
+       }
+
+       @Bean(typeName="Person",p="name,age,addresses")
+       public static class Person {
+               public String name;
+               public int age;
+               public Address[] addresses;
+
+               public Person() {}
+
+               public Person(String name, int age, Address...addresses) {
+                       this.name = name;
+                       this.age = age;
+                       this.addresses = addresses;
+               }
+
+               @Override /* Object */
+               public String toString() {
+                       return "Person(name="+name+",age="+age+")";
+               }
+       }
+
+
+
+}
\ No newline at end of file
diff --git 
a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/LogConfig.java
 
b/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/LogConfig.java
deleted file mode 100644
index 5221f8b85..000000000
--- 
a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/LogConfig.java
+++ /dev/null
@@ -1,211 +0,0 @@
-// 
***************************************************************************************************************************
-// * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license agreements.  See the NOTICE file *
-// * distributed with this work for additional information regarding copyright 
ownership.  The ASF licenses this file        *
-// * to you 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                
                                              *
-// *                                                                           
                                              *
-// *  http://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.apache.juneau.microservice;
-
-import static org.apache.juneau.internal.CollectionUtils.*;
-
-import java.util.*;
-import java.util.logging.*;
-import java.util.logging.Formatter;
-
-import org.apache.juneau.microservice.resources.*;
-
-/**
- * Can be used for configuration of simple logging in the microservice.
- *
- * <p>
- * Instances of this class can be created using {@link #create()} and passing 
the result to
- * {@link Microservice.Builder#logConfig(LogConfig)}.
- *
- * <p>
- * These values override values specified in the <js>"Logging"</js> 
configuration section.
- *
- * <ul class='seealso'>
- *     <li class='link'>{@doc juneau-microservice-core}
- *     <li class='extlink'>{@source}
- * </ul>
- */
-public class LogConfig {
-
-       String logFile, logDir;
-       Boolean append;
-       Integer limit, count;
-       Level fileLevel, consoleLevel;
-       Map<String,Level> levels = map();
-       Formatter formatter;
-
-       LogConfig() {}
-
-       /**
-        * Copy constructor.
-        *
-        * @param copyFrom The log config to copy from.
-        */
-       protected LogConfig(LogConfig copyFrom) {
-               this.logFile = copyFrom.logFile;
-               this.logDir = copyFrom.logDir;
-               this.append = copyFrom.append;
-               this.limit = copyFrom.limit;
-               this.count = copyFrom.count;
-               this.fileLevel = copyFrom.fileLevel;
-               this.consoleLevel = copyFrom.consoleLevel;
-               this.levels = copyOf(copyFrom.levels);
-               this.formatter = copyFrom.formatter;
-       }
-
-       /**
-        * Creates a copy of this log configuration.
-        *
-        * @return A new copy of this log configuration.
-        */
-       public LogConfig copy() {
-               return new LogConfig(this);
-       }
-
-       /**
-        * Creates a new instance of this config.
-        *
-        * @return A new instance of this config.
-        */
-       public static LogConfig create() {
-               return new LogConfig();
-       }
-
-       /**
-        * Returns the name of the log file on the file system to store the log 
file for this microservice.
-        *
-        * <p>
-        * This overrides the configuration value <js>"Logging/logFile"</js>.
-        * If not specified, no file system logging will be used.
-        *
-        * @param logFile The log file.
-        * @return This object.
-        */
-       public LogConfig logFile(String logFile) {
-               this.logFile = logFile;
-               return this;
-       }
-
-       /**
-        * The location of the log directory to create the log file.
-        *
-        * <p>
-        * This overrides the configuration value <js>"Logging/logDir"</js>.
-        * If not specified, uses the JVM working directory.
-        *
-        * @param logDir The log directory location as a path relative to the 
working directory.
-        * @return This object.
-        */
-       public LogConfig logDir(String logDir) {
-               this.logDir = logDir;
-               return this;
-       }
-
-       /**
-        * The log entry formatter.
-        *
-        * <p>
-        * If not specified, uses the following values pulled from the 
configuration to construct a {@link LogEntryFormatter}:
-        * <ul>
-        *      <li><js><js>"Logging/format"</js> (default is <js>"[{date} 
{level}] {msg}%n"</js>)
-        *      <li><js><js>"Logging/dateFormat"</js> (default is 
<js>"yyyy.MM.dd hh:mm:ss"</js>)
-        *      <li><js><js>"Logging/useStackTraceHashes"</js> (default is 
<jk>false</jk>)
-        * </ul>
-        *
-        *
-        * @param formatter The log entry formatter.
-        * @return This object.
-        * @see LogEntryFormatter
-        */
-       public LogConfig formatter(Formatter formatter) {
-               this.formatter = formatter;
-               return this;
-       }
-
-       /**
-        * Specified append mode for the log file.
-        *
-        * @return This object.
-        */
-       public LogConfig append() {
-               this.append = true;
-               return this;
-       }
-
-       /**
-        * The maximum number of bytes to write to any one log file.
-        *
-        * @param limit The number of bytes.
-        * @return This object.
-        */
-       public LogConfig limit(int limit) {
-               this.limit = limit;
-               return this;
-       }
-
-       /**
-        * The number of log files to use.
-        *
-        * @param count The number of log files.
-        * @return This object.
-        */
-       public LogConfig count(int count) {
-               this.count = count;
-               return this;
-       }
-
-       /**
-        * The default logging level for the log file.
-        *
-        * @param fileLevel The logging level.
-        * @return This object.
-        */
-       public LogConfig fileLevel(Level fileLevel) {
-               this.fileLevel = fileLevel;
-               return this;
-       }
-
-       /**
-        * The default logging level for the console.
-        *
-        * @param consoleLevel The logging level.
-        * @return This object.
-        */
-       public LogConfig consoleLevel(Level consoleLevel) {
-               this.consoleLevel = consoleLevel;
-               return this;
-       }
-
-       /**
-        * Default logging levels for loggers.
-        *
-        * @param levels A map of logger names to logger levels.
-        * @return This object.
-        */
-       public LogConfig levels(Map<String,Level> levels) {
-               this.levels.putAll(levels);
-               return this;
-       }
-
-       /**
-        * Default logging level for logger.
-        *
-        * @param logger Logger name.
-        * @param level Logger level.
-        * @return This object.
-        */
-       public LogConfig level(String logger, Level level) {
-               this.levels.put(logger, level);
-               return this;
-       }
-}
diff --git 
a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/Microservice.java
 
b/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/Microservice.java
index 74ac9489c..7f12f0b61 100755
--- 
a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/Microservice.java
+++ 
b/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/Microservice.java
@@ -14,9 +14,7 @@ package org.apache.juneau.microservice;
 
 import static org.apache.juneau.internal.ClassUtils.*;
 import static org.apache.juneau.internal.CollectionUtils.*;
-import static org.apache.juneau.internal.FileUtils.*;
 import static org.apache.juneau.internal.IOUtils.*;
-import static org.apache.juneau.internal.ObjectUtils.*;
 import static org.apache.juneau.internal.StringUtils.*;
 import static org.apache.juneau.internal.ThrowableUtils.*;
 
@@ -28,7 +26,6 @@ import java.util.*;
 import java.util.concurrent.*;
 import java.util.jar.*;
 import java.util.logging.*;
-import java.util.logging.Formatter;
 
 import org.apache.juneau.*;
 import org.apache.juneau.collections.*;
@@ -40,7 +37,6 @@ import org.apache.juneau.config.vars.*;
 import org.apache.juneau.cp.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.microservice.console.*;
-import org.apache.juneau.microservice.resources.*;
 import org.apache.juneau.parser.ParseException;
 import org.apache.juneau.svl.*;
 import org.apache.juneau.svl.vars.*;
@@ -145,7 +141,6 @@ public class Microservice implements ConfigEventListener {
                Args args;
                ManifestFile manifest;
                Logger logger;
-               LogConfig logConfig;
                Config config;
                String configName;
                ConfigStore configStore;
@@ -173,7 +168,6 @@ public class Microservice implements ConfigEventListener {
                        this.manifest = copyFrom.manifest;
                        this.logger = copyFrom.logger;
                        this.configName = copyFrom.configName;
-                       this.logConfig = copyFrom.logConfig == null ? null : 
copyFrom.logConfig.copy();
                        this.consoleEnabled = copyFrom.consoleEnabled;
                        this.configBuilder = copyFrom.configBuilder;
                        this.varResolver = copyFrom.varResolver;
@@ -290,9 +284,6 @@ public class Microservice implements ConfigEventListener {
                /**
                 * Specifies the logger used by the microservice and returned 
by the {@link Microservice#getLogger()} method.
                 *
-                * <p>
-                * Calling this method overrides the default logging mechanism 
controlled by the {@link #logConfig(LogConfig)} method.
-                *
                 * @param logger The logger to use for logging microservice 
messages.
                 * @return This object.
                 */
@@ -301,23 +292,6 @@ public class Microservice implements ConfigEventListener {
                        return this;
                }
 
-               /**
-                * Specifies logging instructions for the microservice.
-                *
-                * <p>
-                * If not specified, the values are taken from the 
<js>"Logging"</js> section of the configuration.
-                *
-                * <p>
-                * This method is ignored if {@link #logger(Logger)} is used to 
set the microservice logger.
-                *
-                * @param logConfig The log configuration.
-                * @return This object.
-                */
-               public Builder logConfig(LogConfig logConfig) {
-                       this.logConfig = logConfig;
-                       return this;
-               }
-
                /**
                 * Specifies the config for initializing this microservice.
                 *
@@ -549,7 +523,6 @@ public class Microservice implements ConfigEventListener {
 
        final Messages messages = Messages.of(Microservice.class);
 
-       private final Builder builder;
        private final Args args;
        private final Config config;
        private final ManifestFile manifest;
@@ -563,7 +536,7 @@ public class Microservice implements ConfigEventListener {
        final File workingDir;
        private final String configName;
 
-       private volatile Logger logger;
+       private volatile Logger logger = Logger.getGlobal();
 
        /**
         * Constructor.
@@ -572,10 +545,8 @@ public class Microservice implements ConfigEventListener {
         * @throws IOException Problem occurred reading file.
         * @throws ParseException Malformed input encountered.
         */
-       @SuppressWarnings("resource")
        protected Microservice(Builder builder) throws IOException, 
ParseException {
                setInstance(this);
-               this.builder = builder.copy();
                this.workingDir = builder.workingDir;
                this.configName = builder.configName;
 
@@ -764,53 +735,6 @@ public class Microservice implements ConfigEventListener {
                        for (String key : spKeys)
                                System.setProperty(key, 
config.get("SystemProperties/"+key).orElse(null));
 
-               // 
--------------------------------------------------------------------------------
-               // Initialize logging.
-               // 
--------------------------------------------------------------------------------
-               this.logger = builder.logger;
-               LogConfig logConfig = builder.logConfig != null ? 
builder.logConfig : new LogConfig();
-               if (this.logger == null) {
-                       LogManager.getLogManager().reset();
-                       this.logger = Logger.getLogger("");
-                       String logFile = firstNonNull(logConfig.logFile, 
config.get("Logging/logFile").orElse(null));
-
-                       if (isNotEmpty(logFile)) {
-                               String logDir = firstNonNull(logConfig.logDir, 
config.get("Logging/logDir").orElse("."));
-                               File logDirFile = resolveFile(logDir);
-                               mkdirs(logDirFile, false);
-                               logDir = logDirFile.getAbsolutePath();
-                               System.setProperty("juneau.logDir", logDir);
-
-                               boolean append = firstNonNull(logConfig.append, 
config.get("Logging/append").asBoolean().orElse(false));
-                               int limit = firstNonNull(logConfig.limit, 
config.get("Logging/limit").asInteger().orElse(1024*1024));
-                               int count = firstNonNull(logConfig.count, 
config.get("Logging/count").asInteger().orElse(1));
-
-                               FileHandler fh = new FileHandler(logDir + '/' + 
logFile, limit, count, append);
-
-                               Formatter f = logConfig.formatter;
-                               if (f == null) {
-                                       String format = 
config.get("Logging/format").orElse("[{date} {level}] {msg}%n");
-                                       String dateFormat = 
config.get("Logging/dateFormat").orElse("yyyy.MM.dd hh:mm:ss");
-                                       boolean useStackTraceHashes = 
config.get("Logging/useStackTraceHashes").asBoolean().orElse(false);
-                                       f = new LogEntryFormatter(format, 
dateFormat, useStackTraceHashes);
-                               }
-                               fh.setFormatter(f);
-                               fh.setLevel(firstNonNull(logConfig.fileLevel, 
config.get("Logging/fileLevel").as(Level.class).orElse(Level.INFO)));
-                               logger.addHandler(fh);
-
-                               ConsoleHandler ch = new ConsoleHandler();
-                               
ch.setLevel(firstNonNull(logConfig.consoleLevel, 
config.get("Logging/consoleLevel").as(Level.class).orElse(Level.WARNING)));
-                               ch.setFormatter(f);
-                               logger.addHandler(ch);
-                       }
-               }
-
-               JsonMap loggerLevels = 
config.get("Logging/levels").as(JsonMap.class).orElseGet(JsonMap::new);
-               for (String l : loggerLevels.keySet())
-                       Logger.getLogger(l).setLevel(loggerLevels.get(l, 
Level.class));
-               for (String l : logConfig.levels.keySet())
-                       Logger.getLogger(l).setLevel(logConfig.levels.get(l));
-
                return this;
        }
 
diff --git 
a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/LogEntryFormatter.java
 
b/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/LogEntryFormatter.java
deleted file mode 100644
index 5b8d915b0..000000000
--- 
a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/LogEntryFormatter.java
+++ /dev/null
@@ -1,272 +0,0 @@
-// 
***************************************************************************************************************************
-// * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license agreements.  See the NOTICE file *
-// * distributed with this work for additional information regarding copyright 
ownership.  The ASF licenses this file        *
-// * to you 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                
                                              *
-// *                                                                           
                                              *
-// *  http://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.apache.juneau.microservice.resources;
-
-import static org.apache.juneau.internal.CollectionUtils.*;
-import static org.apache.juneau.internal.ThrowableUtils.*;
-
-import java.text.*;
-import java.util.*;
-import java.util.concurrent.*;
-import java.util.concurrent.atomic.*;
-import java.util.logging.*;
-import java.util.logging.Formatter;
-import java.util.regex.*;
-
-/**
- * Log entry formatter.
- *
- * <p>
- * Uses three simple parameter for configuring log entry formats:
- * <ul class='spaced-list'>
- *     <li>
- *             <c>dateFormat</c> - A {@link SimpleDateFormat} string 
describing the format for dates.
- *     <li>
- *             <c>format</c> - A string with <c>{...}</c> replacement 
variables representing predefined fields.
- *     <li>
- *             <c>useStackTraceHashes</c> - A setting that causes duplicate 
stack traces to be replaced with 8-character
- *              hash strings.
- * </ul>
- *
- * <p>
- * This class converts the format strings into a regular expression that can 
be used to parse the resulting log file.
- *
- * <ul class='seealso'>
- *     <li class='link'>{@doc juneau-microservice-core}
- *     <li class='extlink'>{@source}
- * </ul>
- */
-public class LogEntryFormatter extends Formatter {
-
-       private ConcurrentHashMap<String,AtomicInteger> hashes;
-       private DateFormat df;
-       private String format;
-       private Pattern rePattern;
-       private Map<String,Integer> fieldIndexes;
-
-       /**
-        * Create a new formatter.
-        *
-        * @param format
-        *      The log entry format.  e.g. <js>"[{date} {level}] {msg}%n"</js>
-        *      The string can contain any of the following variables:
-        *      <ol>
-        *              <li><js>"{date}"</js> - The date, formatted per 
<js>"Logging/dateFormat"</js>.
-        *              <li><js>"{class}"</js> - The class name.
-        *              <li><js>"{method}"</js> - The method name.
-        *              <li><js>"{logger}"</js> - The logger name.
-        *              <li><js>"{level}"</js> - The log level name.
-        *              <li><js>"{msg}"</js> - The log message.
-        *              <li><js>"{threadid}"</js> - The thread ID.
-        *              <li><js>"{exception}"</js> - The localized exception 
message.
-        *      </ol>
-        * @param dateFormat
-        *      The {@link SimpleDateFormat} format to use for dates.  e.g. 
<js>"yyyy.MM.dd hh:mm:ss"</js>.
-        * @param useStackTraceHashes
-        *      If <jk>true</jk>, only print unique stack traces once and then 
refer to them by a simple 8 character hash
-        *      identifier.
-        */
-       public LogEntryFormatter(String format, String dateFormat, boolean 
useStackTraceHashes) {
-               this.df = new SimpleDateFormat(dateFormat);
-               if (useStackTraceHashes)
-                       hashes = new ConcurrentHashMap<>();
-
-               fieldIndexes = new HashMap<>();
-
-               format = format
-                       .replaceAll("\\{date\\}", "%1\\$s")
-                       .replaceAll("\\{class\\}", "%2\\$s")
-                       .replaceAll("\\{method\\}", "%3\\$s")
-                       .replaceAll("\\{logger\\}", "%4\\$s")
-                       .replaceAll("\\{level\\}", "%5\\$s")
-                       .replaceAll("\\{msg\\}", "%6\\$s")
-                       .replaceAll("\\{threadid\\}", "%7\\$s")
-                       .replaceAll("\\{exception\\}", "%8\\$s");
-
-               this.format = format;
-
-               // Construct a regular expression to match this log entry.
-               int index = 1;
-               StringBuilder re = new StringBuilder();
-               int S1 = 1; // Looking for %
-               int S2 = 2; // Found %, looking for number.
-               int S3 = 3; // Found number, looking for $.
-               int S4 = 4; // Found $, looking for s.
-               int state = 1;
-               int i1 = 0;
-               for (int i = 0; i < format.length(); i++) {
-                       char c = format.charAt(i);
-                       if (state == S1) {
-                               if (c == '%')
-                                       state = S2;
-                               else {
-                                       if (! (Character.isLetterOrDigit(c) || 
Character.isWhitespace(c)))
-                                               re.append('\\');
-                                       re.append(c);
-                               }
-                       } else if (state == S2) {
-                               if (Character.isDigit(c)) {
-                                       i1 = i;
-                                       state = S3;
-                               } else {
-                                       re.append("\\%").append(c);
-                                       state = S1;
-                               }
-                       } else if (state == S3) {
-                               if (c == '$') {
-                                       state = S4;
-                               } else {
-                                       
re.append("\\%").append(format.substring(i1, i));
-                                       state = S1;
-                               }
-                       } else if (state == S4) {
-                               if (c == 's') {
-                                       int group = 
Integer.parseInt(format.substring(i1, i-1));
-                                       switch (group) {
-                                               case 1:
-                                                       
fieldIndexes.put("date", index++);
-                                                       re.append("(" + 
dateFormat.replaceAll("[mHhsSdMy]", "\\\\d").replaceAll("\\.", "\\\\.") + ")");
-                                                       break;
-                                               case 2:
-                                                       
fieldIndexes.put("class", index++);
-                                                       
re.append("([\\p{javaJavaIdentifierPart}\\.]+)");
-                                                       break;
-                                               case 3:
-                                                       
fieldIndexes.put("method", index++);
-                                                       
re.append("([\\p{javaJavaIdentifierPart}\\.]+)");
-                                                       break;
-                                               case 4:
-                                                       
fieldIndexes.put("logger", index++);
-                                                       
re.append("([\\w\\d\\.\\_]+)");
-                                                       break;
-                                               case 5:
-                                                       
fieldIndexes.put("level", index++);
-                                                       
re.append("(SEVERE|WARNING|INFO|CONFIG|FINE|FINER|FINEST)");
-                                                       break;
-                                               case 6:
-                                                       fieldIndexes.put("msg", 
index++);
-                                                       re.append("(.*)");
-                                                       break;
-                                               case 7:
-                                                       
fieldIndexes.put("threadid", index++);
-                                                       re.append("(\\\\d+)");
-                                                       break;
-                                               case 8:
-                                                       
fieldIndexes.put("exception", index++);
-                                                       re.append("(.*)");
-                                                       break;
-                                               default: // Fall through.
-                                       }
-                               } else {
-                                       
re.append("\\%").append(format.substring(i1, i));
-                               }
-                               state = S1;
-                       }
-               }
-
-               // The log parser
-               String sre = re.toString();
-               if (sre.endsWith("\\%n"))
-                       sre = sre.substring(0, sre.length()-3);
-
-               // Replace instances of %n.
-               sre = sre.replaceAll("\\\\%n", "\\\\n");
-
-               rePattern = Pattern.compile(sre);
-               fieldIndexes = unmodifiable(fieldIndexes);
-       }
-
-       /**
-        * Returns the regular expression pattern used for matching log entries.
-        *
-        * @return The regular expression pattern used for matching log entries.
-        */
-       public Pattern getLogEntryPattern() {
-               return rePattern;
-       }
-
-       /**
-        * Returns the {@link DateFormat} used for matching dates.
-        *
-        * @return The {@link DateFormat} used for matching dates.
-        */
-       public DateFormat getDateFormat() {
-               return df;
-       }
-
-       /**
-        * Given a matcher that has matched the pattern specified by {@link 
#getLogEntryPattern()}, returns the field value
-        * from the match.
-        *
-        * @param fieldName
-        *      The field name.
-        *      Possible values are:
-        *      <ul>
-        *              <li><js>"date"</js>
-        *              <li><js>"class"</js>
-        *              <li><js>"method"</js>
-        *              <li><js>"logger"</js>
-        *              <li><js>"level"</js>
-        *              <li><js>"msg"</js>
-        *              <li><js>"threadid"</js>
-        *              <li><js>"exception"</js>
-        *      </ul>
-        * @param m The matcher.
-        * @return The field value, or <jk>null</jk> if the specified field 
does not exist.
-        */
-       public String getField(String fieldName, Matcher m) {
-               Integer i = fieldIndexes.get(fieldName);
-               return (i == null ? null : m.group(i));
-       }
-
-       @Override /* Formatter */
-       public String format(LogRecord r) {
-               String msg = formatMessage(r);
-               Throwable t = r.getThrown();
-               String hash = null;
-               int c = 0;
-               if (hashes != null && t != null) {
-                       hash = hashCode(t);
-                       hashes.putIfAbsent(hash, new AtomicInteger(0));
-                       c = hashes.get(hash).incrementAndGet();
-                       if (c <= 5) {
-                               msg = '[' + hash + '.' + c + "] " + msg;
-                       } else {
-                               msg = '[' + hash + '.' + c + "] " + msg + ", " 
+ t.getLocalizedMessage();
-                               t = null;
-                       }
-               }
-               String s = String.format(format,
-                       df.format(new Date(r.getMillis())),
-                       r.getSourceClassName(),
-                       r.getSourceMethodName(),
-                       r.getLoggerName(),
-                       r.getLevel(),
-                       msg,
-                       r.getThreadID(),
-                       r.getThrown() == null ? "" : 
r.getThrown().getMessage());
-               if (t != null)
-                       s += String.format("%s", getStackTrace(r.getThrown()));
-               return s;
-       }
-
-       private static String hashCode(Throwable t) {
-               int i = 0;
-               while (t != null) {
-                       for (StackTraceElement e : t.getStackTrace())
-                               i ^= e.hashCode();
-                       t = t.getCause();
-               }
-               return Integer.toHexString(i);
-       }
-}
diff --git 
a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/LogParser.java
 
b/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/LogParser.java
deleted file mode 100644
index 7e1b310e8..000000000
--- 
a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/LogParser.java
+++ /dev/null
@@ -1,234 +0,0 @@
-// 
***************************************************************************************************************************
-// * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license agreements.  See the NOTICE file *
-// * distributed with this work for additional information regarding copyright 
ownership.  The ASF licenses this file        *
-// * to you 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                
                                              *
-// *                                                                           
                                              *
-// *  http://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.apache.juneau.microservice.resources;
-
-import static org.apache.juneau.internal.CollectionUtils.*;
-import static org.apache.juneau.internal.ThrowableUtils.*;
-
-import java.io.*;
-import java.nio.charset.*;
-import java.text.*;
-import java.util.*;
-import java.util.regex.*;
-
-/**
- * Utility class for reading log files.
- *
- * <p>
- * Provides the capability of returning splices of log files based on dates 
and filtering based on thread and logger
- * names.
- *
- * <ul class='seealso'>
- *     <li class='link'>{@doc juneau-microservice-core}
- *     <li class='extlink'>{@source}
- * </ul>
- */
-public final class LogParser implements Iterable<LogParser.Entry>, 
Iterator<LogParser.Entry>, Closeable {
-       private BufferedReader br;
-       LogEntryFormatter formatter;
-       Date start, end;
-       Set<String> loggerFilter, severityFilter;
-       String threadFilter;
-       private Entry next;
-
-       /**
-        * Constructor.
-        *
-        * @param formatter The log entry formatter.
-        * @param f The log file.
-        * @param start Don't return rows before this date.  If <jk>null</jk>, 
start from the beginning of the file.
-        * @param end Don't return rows after this date.  If <jk>null</jk>, go 
to the end of the file.
-        * @param thread Only return log entries with this thread name.
-        * @param loggers Only return log entries produced by these loggers 
(simple class names).
-        * @param severity Only return log entries with the specified severity.
-        * @throws IOException Thrown by underlying stream.
-        */
-       public LogParser(LogEntryFormatter formatter, File f, Date start, Date 
end, String thread, String[] loggers, String[] severity) throws IOException {
-               br = new BufferedReader(new InputStreamReader(new 
FileInputStream(f), Charset.defaultCharset()));
-               this.formatter = formatter;
-               this.start = start;
-               this.end = end;
-               this.threadFilter = thread;
-               if (loggers != null)
-                       this.loggerFilter = set(loggers);
-               if (severity != null)
-                       this.severityFilter = set(severity);
-
-               // Find the first line.
-               String line;
-               while (next == null && (line = br.readLine()) != null) {
-                       Entry e = new Entry(line);
-                       if (e.matches())
-                               next = e;
-               }
-       }
-
-       @Override /* Iterator */
-       public boolean hasNext() {
-               return next != null;
-       }
-
-       @Override /* Iterator */
-       public Entry next() {
-               Entry current = next;
-               Entry prev = next;
-               try {
-                       next = null;
-                       String line = null;
-                       while (next == null && (line = br.readLine()) != null) {
-                               Entry e = new Entry(line);
-                               if (e.isRecord) {
-                                       if (e.matches())
-                                               next = e;
-                                       prev = null;
-                               } else {
-                                       if (prev != null)
-                                               prev.addText(e.line);
-                               }
-                       }
-               } catch (IOException e) {
-                       throw runtimeException(e);
-               }
-               return current;
-       }
-
-       @Override /* Iterator */
-       public void remove() {
-               throw new NoSuchMethodError();
-       }
-
-       @Override /* Iterable */
-       public Iterator<Entry> iterator() {
-               return this;
-       }
-
-       @Override /* Closeable */
-       public void close() throws IOException {
-               br.close();
-       }
-
-       /**
-        * Serializes the contents of the parsed log file to the specified 
writer and then closes the underlying reader.
-        *
-        * @param w The writer to write the log file to.
-        * @throws IOException Thrown by underlying stream.
-        */
-       public void writeTo(Writer w) throws IOException {
-               try {
-                       if (! hasNext())
-                               w.append("[EMPTY]");
-                       else {
-                               forEach(le -> safeRun(()->le.append(w)));
-                       }
-               } finally {
-                       close();
-               }
-       }
-
-       /**
-        * Represents a single line from the log file.
-        */
-       @SuppressWarnings("javadoc")
-       public final class Entry {
-               public Date date;
-               public String severity, logger;
-               protected String line, text;
-               protected String thread;
-               protected List<String> additionalText;
-               protected boolean isRecord;
-
-               Entry(String line) throws IOException {
-                       try {
-                               this.line = line;
-                               Matcher m = 
formatter.getLogEntryPattern().matcher(line);
-                               if (m.matches()) {
-                                       isRecord = true;
-                                       String s = formatter.getField("date", 
m);
-                                       if (s != null)
-                                               date = 
formatter.getDateFormat().parse(s);
-                                       thread = formatter.getField("thread", 
m);
-                                       severity = formatter.getField("level", 
m);
-                                       logger = formatter.getField("logger", 
m);
-                                       text = formatter.getField("msg", m);
-                                       if (logger != null && 
logger.indexOf('.') > -1)
-                                               logger = 
logger.substring(logger.lastIndexOf('.')+1);
-                               }
-                       } catch (ParseException e) {
-                               throw ioException(e);
-                       }
-               }
-
-               void addText(String t) {
-                       if (additionalText == null)
-                               additionalText = new LinkedList<>();
-                       additionalText.add(t);
-               }
-
-               public String getText() {
-                       if (additionalText == null)
-                               return text;
-                       if (text == null)
-                               return "";
-                       int i = text.length();
-                       for (String s : additionalText)
-                               i += s.length() + 1;
-                       StringBuilder sb = new StringBuilder(i);
-                       sb.append(text);
-                       additionalText.forEach(s -> sb.append('\n').append(s));
-                       return sb.toString();
-               }
-
-               public String getThread() {
-                       return thread;
-               }
-
-               public Writer appendHtml(Writer w) throws IOException {
-                       w.append(toHtml(line)).append("<br>");
-                       if (additionalText != null)
-                               for (String t : additionalText)
-                                       w.append(toHtml(t)).append("<br>");
-                       return w;
-               }
-
-               protected Writer append(Writer w) throws IOException {
-                       w.append(line).append('\n');
-                       if (additionalText != null)
-                               for (String t : additionalText)
-                                       w.append(t).append('\n');
-                       return w;
-               }
-
-               boolean matches() {
-                       if (! isRecord)
-                               return false;
-                       if (start != null && date.before(start))
-                               return false;
-                       if (end != null && date.after(end))
-                               return false;
-                       if (threadFilter != null && ! 
threadFilter.equals(thread))
-                               return false;
-                       if (loggerFilter != null && ! 
loggerFilter.contains(logger))
-                               return false;
-                       if (severityFilter != null && ! 
severityFilter.contains(severity))
-                               return false;
-                       return true;
-               }
-       }
-
-       static final String toHtml(String s) {
-               if (s.indexOf('<') != -1)
-                       return s.replaceAll("<", "&lt;");//$NON-NLS-2$
-               return s;
-       }
-}
-
diff --git 
a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/LogsResource.java
 
b/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/LogsResource.java
deleted file mode 100755
index fb1da1227..000000000
--- 
a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/LogsResource.java
+++ /dev/null
@@ -1,373 +0,0 @@
-// 
***************************************************************************************************************************
-// * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license agreements.  See the NOTICE file *
-// * distributed with this work for additional information regarding copyright 
ownership.  The ASF licenses this file        *
-// * to you 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                
                                              *
-// *                                                                           
                                              *
-// *  http://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.apache.juneau.microservice.resources;
-
-import static org.apache.juneau.internal.CollectionUtils.*;
-import static org.apache.juneau.internal.StringUtils.*;
-
-import java.io.*;
-import java.nio.charset.*;
-import java.util.*;
-
-import org.apache.juneau.annotation.*;
-import org.apache.juneau.config.*;
-import org.apache.juneau.dto.*;
-import org.apache.juneau.html.annotation.*;
-import org.apache.juneau.http.annotation.*;
-import org.apache.juneau.http.response.*;
-import org.apache.juneau.rest.*;
-import org.apache.juneau.rest.annotation.*;
-import org.apache.juneau.rest.beans.*;
-import org.apache.juneau.rest.config.*;
-import org.apache.juneau.rest.converter.*;
-import org.apache.juneau.rest.servlet.*;
-
-/**
- * REST resource for viewing and accessing log files.
- *
- * <ul class='seealso'>
- *     <li class='link'>{@doc juneau-microservice-core}
- *     <li class='extlink'>{@source}
- * </ul>
- *
- * @serial exclude
- */
-@Rest(
-       path="/logs",
-       title="Log files",
-       description="Log files from this service",
-       allowedMethodParams="*"
-)
-@HtmlConfig(uriAnchorText="PROPERTY_NAME")
-@SuppressWarnings("javadoc")
-public class LogsResource extends BasicRestServlet implements 
BasicUniversalConfig {
-       private static final long serialVersionUID = 1L;
-
-       
//-------------------------------------------------------------------------------------------------------------------
-       // Configurable properties
-       
//-------------------------------------------------------------------------------------------------------------------
-
-       private static final String PREFIX = "LogsResource.";
-
-       /**
-        * Root directory.
-        */
-       public static final String LOGS_RESOURCE_logDir = PREFIX + "logDir.s";
-
-       /**
-        * Allow deletes on files.
-        */
-       public static final String LOGS_RESOURCE_allowDeletes = PREFIX + 
"allowDeletes.b";
-
-       /**
-        * Log entry format.
-        */
-       public static final String LOGS_RESOURCE_logFormat = PREFIX + 
"logFormat.s";
-
-       /**
-        * Log entry format.
-        */
-       public static final String LOGS_RESOURCE_dateFormat = PREFIX + 
"dateFormat.s";
-
-       /**
-        * Log entry format.
-        */
-       public static final String LOGS_RESOURCE_useStackTraceHashes = PREFIX + 
"useStackTraceHashes.b";
-
-       
//-------------------------------------------------------------------------------------------------------------------
-       // Instance
-       
//-------------------------------------------------------------------------------------------------------------------
-
-       private final File logDir;
-       private final LogEntryFormatter leFormatter;
-       final boolean allowDeletes;
-
-       public LogsResource(Config c) {
-               logDir = new File(c.get(LOGS_RESOURCE_logDir).orElse("logDir"));
-               allowDeletes = 
c.get(LOGS_RESOURCE_allowDeletes).asBoolean().orElse(true);
-               leFormatter = new LogEntryFormatter(
-                       c.get(LOGS_RESOURCE_logFormat).orElse("[{date} {level}] 
{msg}%n"),
-                       c.get(LOGS_RESOURCE_dateFormat).orElse("yyyy.MM.dd 
hh:mm:ss"),
-                       
c.get(LOGS_RESOURCE_useStackTraceHashes).asBoolean().orElse(true)
-               );
-       }
-
-       @RestGet(
-               path="/*",
-               summary="View information on file or directory",
-               description="Returns information about the specified file or 
directory."
-       )
-       @HtmlDocConfig(
-               nav={"<h5>Folder:  $RA{fullPath}</h5>"}
-       )
-       public FileResource getFile(RestRequest req, @Path("/*") String path) 
throws NotFound, Exception {
-
-               File dir = getFile(path);
-               req.setAttribute("fullPath", dir.getAbsolutePath());
-
-               return new FileResource(dir, path, allowDeletes, true);
-       }
-
-       @RestOp(
-               method="VIEW",
-               path="/*",
-               summary="View contents of log file",
-               description="View the contents of a log file."
-       )
-       public void viewFile(
-                       RestResponse res,
-                       @Path("/*") String path,
-                       @Query("highlight") @Schema(d="Add severity color 
highlighting.") boolean highlight,
-                       @Query("start") @Schema(d="Start timestamp (ISO8601, 
full or partial).\nDon't print lines logged before the specified 
timestamp.\nUse any of the following formats: yyyy, yyyy-MM, yyyy-MM-dd, 
yyyy-MM-ddThh, yyyy-MM-ddThh:mm, yyyy-MM-ddThh:mm:ss, yyyy-MM-ddThh:mm:ss.SSS") 
String start,
-                       @Query("end") @Schema(d="End timestamp (ISO8601, full 
or partial).\nDon't print lines logged after the specified timestamp.\nUse any 
of the following formats: yyyy, yyyy-MM, yyyy-MM-dd, yyyy-MM-ddThh, 
yyyy-MM-ddThh:mm, yyyy-MM-ddThh:mm:ss, yyyy-MM-ddThh:mm:ss.SSS") String end,
-                       @Query("thread") @Schema(d="Thread name filter.\nOnly 
show log entries with the specified thread name.") String thread,
-                       @Query("loggers") @Schema(d="Logger filter (simple 
class name).\nOnly show log entries if they were produced by one of the 
specified loggers.") String[] loggers,
-                       @Query("severity") @Schema(d="Severity filter.\nOnly 
show log entries with the specified severity.") String[] severity
-               ) throws NotFound, MethodNotAllowed, IOException {
-
-               File f = getFile(path);
-
-               Date startDate = parseIsoDate(start), endDate = 
parseIsoDate(end);
-
-               if (! highlight) {
-                       Object o = getReader(f, startDate, endDate, thread, 
loggers, severity);
-                       res.setContentType("text/plain");
-                       if (o instanceof Reader)
-                               res.setContent(o);
-                       else {
-                               try (LogParser p = (LogParser)o; Writer w = 
res.getNegotiatedWriter()) {
-                                       p.writeTo(w);
-                               }
-                       }
-                       return;
-               }
-
-               res.setContentType("text/html");
-               try (PrintWriter w = res.getNegotiatedWriter()) {
-                       w.println("<html><body 
style='font-family:monospace;font-size:8pt;white-space:pre;'>");
-                       try (LogParser lp = getLogParser(f, startDate, endDate, 
thread, loggers, severity)) {
-                               if (! lp.hasNext())
-                                       w.append("<span 
style='color:gray'>[EMPTY]</span>");
-                               else for (LogParser.Entry le : lp) {
-                                       char s = le.severity.charAt(0);
-                                       String color = "black";
-                                       
//SEVERE|WARNING|INFO|CONFIG|FINE|FINER|FINEST
-                                       if (s == 'I')
-                                               color = "#006400";
-                                       else if (s == 'W')
-                                               color = "#CC8400";
-                                       else if (s == 'E' || s == 'S')
-                                               color = "#DD0000";
-                                       else if (s == 'D' || s == 'F' || s == 
'T')
-                                               color = "#000064";
-                                       w.append("<span 
style='color:").append(color).append("'>");
-                                       le.appendHtml(w).append("</span>");
-                               }
-                               w.append("</body></html>");
-                       }
-               }
-       }
-
-       @RestOp(
-               method="PARSE",
-               path="/*",
-               converters=Queryable.class,
-               summary="View parsed contents of file",
-               description="View the parsed contents of a file.",
-               swagger=@OpSwagger(
-                       parameters={
-                                Queryable.SWAGGER_PARAMS
-                       }
-               )
-       )
-       @HtmlDocConfig(
-               nav={"<h5>Folder:  $RA{fullPath}</h5>"}
-       )
-       public LogParser viewParsedEntries(
-                       RestRequest req,
-                       @Path("/*") String path,
-                       @Query("start") @Schema(d="Start timestamp (ISO8601, 
full or partial).\nDon't print lines logged before the specified 
timestamp.\nUse any of the following formats: yyyy, yyyy-MM, yyyy-MM-dd, 
yyyy-MM-ddThh, yyyy-MM-ddThh:mm, yyyy-MM-ddThh:mm:ss, yyyy-MM-ddThh:mm:ss.SSS") 
String start,
-                       @Query("end") @Schema(d="End timestamp (ISO8601, full 
or partial).\nDon't print lines logged after the specified timestamp.\nUse any 
of the following formats: yyyy, yyyy-MM, yyyy-MM-dd, yyyy-MM-ddThh, 
yyyy-MM-ddThh:mm, yyyy-MM-ddThh:mm:ss, yyyy-MM-ddThh:mm:ss.SSS") String end,
-                       @Query("thread") @Schema(d="Thread name filter.\nOnly 
show log entries with the specified thread name.") String thread,
-                       @Query("loggers") @Schema(d="Logger filter (simple 
class name).\nOnly show log entries if they were produced by one of the 
specified loggers.") String[] loggers,
-                       @Query("severity") @Schema(d="Severity filter.\nOnly 
show log entries with the specified severity.") String[] severity
-               ) throws NotFound, IOException {
-
-               File f = getFile(path);
-               req.setAttribute("fullPath", f.getAbsolutePath());
-
-               Date startDate = parseIsoDate(start), endDate = 
parseIsoDate(end);
-
-               return getLogParser(f, startDate, endDate, thread, loggers, 
severity);
-       }
-
-       @RestOp(
-               method="DOWNLOAD",
-               path="/*",
-               summary="Download file",
-               description="Download the contents of a file.\nContent-Type is 
set to 'application/octet-stream'."
-       )
-       public FileContents downloadFile(RestResponse res, @Path("/*") String 
path) throws NotFound, MethodNotAllowed {
-               res.setContentType("application/octet-stream");
-               try {
-                       return new FileContents(getFile(path));
-               } catch (FileNotFoundException e) {
-                       throw new NotFound("File not found");
-               }
-       }
-
-       @RestDelete(
-               path="/*",
-               summary="Delete log file",
-               description="Delete a log file on the file system."
-       )
-       public RedirectToRoot deleteFile(@Path("/*") String path) throws 
MethodNotAllowed {
-               deleteFile(getFile(path));
-               return new RedirectToRoot();
-       }
-
-
-       
//-----------------------------------------------------------------------------------------------------------------
-       // Helper beans
-       
//-----------------------------------------------------------------------------------------------------------------
-
-       @Response @Schema(type="string",format="binary",description="Contents 
of file")
-       static class FileContents extends FileInputStream {
-               public FileContents(File file) throws FileNotFoundException {
-                       super(file);
-               }
-       }
-
-       @Response @Schema(description="Redirect to root page on success")
-       static class RedirectToRoot extends SeeOtherRoot {}
-
-       @Response @Schema(description="File action")
-       public static class Action extends LinkString {
-               public Action(String name, String uri, Object...uriArgs) {
-                       super(name, uri, uriArgs);
-               }
-       }
-
-       @Response @Schema(description="File or directory details")
-       @Bean(properties="type,name,size,lastModified,actions,files")
-       public static class FileResource {
-               private final File f;
-               private final String path;
-               private final String uri;
-               private final boolean includeChildren, allowDeletes;
-
-               public FileResource(File f, String path, boolean allowDeletes, 
boolean includeChildren) {
-                       this.f = f;
-                       this.path = path;
-                       this.uri = "servlet:/"+(path == null ? "" : path);
-                       this.includeChildren = includeChildren;
-                       this.allowDeletes = allowDeletes;
-               }
-
-               public String getType() {
-                       return (f.isDirectory() ? "dir" : "file");
-               }
-
-               public LinkString getName() {
-                       return new LinkString(f.getName(), uri);
-               }
-
-               public long getSize() {
-                       return f.isDirectory() ? f.listFiles().length : 
f.length();
-               }
-
-               public Date getLastModified() {
-                       return new Date(f.lastModified());
-               }
-
-               @Html(format=HtmlFormat.HTML_CDC)
-               public List<Action> getActions() throws Exception {
-                       List<Action> l = list();
-                       if (f.canRead() && ! f.isDirectory()) {
-                               l.add(new Action("view", uri + "?method=VIEW"));
-                               l.add(new Action("highlighted", uri + 
"?method=VIEW&highlight=true"));
-                               l.add(new Action("parsed", uri + 
"?method=PARSE"));
-                               l.add(new Action("download", uri + 
"?method=DOWNLOAD"));
-                               if (allowDeletes)
-                                       l.add(new Action("delete", uri + 
"?method=DELETE"));
-                       }
-                       return l;
-               }
-
-               public Set<FileResource> getFiles() {
-                       if (f.isFile() || ! includeChildren)
-                               return null;
-                       Set<FileResource> s = new TreeSet<>(FILE_COMPARATOR);
-                       for (File fc : f.listFiles(FILE_FILTER))
-                               s.add(new FileResource(fc, (path != null ? 
(path + '/') : "") + urlEncode(fc.getName()), allowDeletes, false));
-                       return s;
-               }
-
-               static final FileFilter FILE_FILTER = new FileFilter() {
-                       @Override /* FileFilter */
-                       public boolean accept(File f) {
-                               return f.isDirectory() || 
f.getName().endsWith(".log");
-                       }
-               };
-
-               static final Comparator<FileResource> FILE_COMPARATOR = new 
Comparator<FileResource>() {
-                       @Override /* Comparator */
-                       public int compare(FileResource o1, FileResource o2) {
-                               int c = o1.getType().compareTo(o2.getType());
-                               return c != 0 ? c : 
o1.getName().compareTo(o2.getName());
-                       }
-               };
-       }
-
-
-       
//-----------------------------------------------------------------------------------------------------------------
-       // Helper methods
-       
//-----------------------------------------------------------------------------------------------------------------
-
-       private File getFile(String path) throws NotFound {
-               if (path == null)
-                       return logDir;
-               File f = new File(logDir.getAbsolutePath() + '/' + path);
-               if (f.exists())
-                       return f;
-               throw new NotFound("File not found.");
-       }
-
-       private void deleteFile(File f) {
-               if (! allowDeletes)
-                       throw new MethodNotAllowed("DELETE not enabled");
-               if (f.isDirectory()) {
-                       File[] files = f.listFiles();
-                       if (files != null) {
-                               for (File fc : files)
-                                       deleteFile(fc);
-                       }
-               }
-               if (! f.delete())
-                       throw new Forbidden("Could not delete file {0}", 
f.getAbsolutePath()) ;
-       }
-
-       private static BufferedReader getReader(File f) throws IOException {
-               return new BufferedReader(new InputStreamReader(new 
FileInputStream(f), Charset.defaultCharset()));
-       }
-
-       private Object getReader(File f, final Date start, final Date end, 
final String thread, final String[] loggers, final String[] severity) throws 
IOException {
-               if (start == null && end == null && thread == null && loggers 
== null)
-                       return getReader(f);
-               return getLogParser(f, start, end, thread, loggers, severity);
-       }
-
-       private LogParser getLogParser(File f, final Date start, final Date 
end, final String thread, final String[] loggers, final String[] severity) 
throws IOException {
-               return new LogParser(leFormatter, f, start, end, thread, 
loggers, severity);
-       }
-}
diff --git 
a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/SampleRootResource.java
 
b/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/SampleRootResource.java
index 46ceccf5e..4f3a68257 100755
--- 
a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/SampleRootResource.java
+++ 
b/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/SampleRootResource.java
@@ -30,7 +30,7 @@ import org.apache.juneau.rest.servlet.*;
        path="/",
        title="Sample Root Resource",
        description="This is a sample router page",
-       children={ConfigResource.class,LogsResource.class}
+       children={ConfigResource.class}
 )
 public class SampleRootResource extends BasicRestServletGroup implements 
BasicUniversalConfig {
        private static final long serialVersionUID = 1L;
diff --git 
a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/Root.java
 
b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/Root.java
index d382b039d..80f3efc74 100644
--- 
a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/Root.java
+++ 
b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/Root.java
@@ -27,7 +27,6 @@ import org.apache.juneau.rest.test.client.*;
        path="/*",
        children={
                DebugResource.class,
-               LogsResource.class,
                ConfigResource.class,
                LargePojosResource.class,
                ThirdPartyProxyResource.class,
diff --git 
a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/ThirdPartyProxyResource.java
 
b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/ThirdPartyProxyResource.java
index e32eac2e1..193375a41 100644
--- 
a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/ThirdPartyProxyResource.java
+++ 
b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/ThirdPartyProxyResource.java
@@ -45,6 +45,7 @@ public class ThirdPartyProxyResource extends BasicRestServlet 
implements BasicUn
        public static FileWriter logFile;
        static {
                try {
+                       new File("./target/logs").mkdirs();
                        logFile = new 
FileWriter("./target/logs/third-party-proxy-resource.txt", false);
                } catch (IOException e) {
                        e.printStackTrace();
diff --git 
a/juneau-microservice/juneau-microservice-jetty/src/main/java/org/apache/juneau/microservice/jetty/JettyMicroservice.java
 
b/juneau-microservice/juneau-microservice-jetty/src/main/java/org/apache/juneau/microservice/jetty/JettyMicroservice.java
index 9c1f86162..04b89d3df 100644
--- 
a/juneau-microservice/juneau-microservice-jetty/src/main/java/org/apache/juneau/microservice/jetty/JettyMicroservice.java
+++ 
b/juneau-microservice/juneau-microservice-jetty/src/main/java/org/apache/juneau/microservice/jetty/JettyMicroservice.java
@@ -371,12 +371,6 @@ public class JettyMicroservice extends Microservice {
                        return this;
                }
 
-               @Override /* MicroserviceBuilder */
-               public Builder logConfig(LogConfig logConfig) {
-                       super.logConfig(logConfig);
-                       return this;
-               }
-
                @Override /* MicroserviceBuilder */
                public Builder config(Config config) {
                        super.config(config);
diff --git 
a/juneau-microservice/juneau-my-jetty-microservice/src/main/java/org/apache/juneau/microservice/jetty/template/RootResources.java
 
b/juneau-microservice/juneau-my-jetty-microservice/src/main/java/org/apache/juneau/microservice/jetty/template/RootResources.java
index 7d22c775b..fd74c7ae8 100755
--- 
a/juneau-microservice/juneau-my-jetty-microservice/src/main/java/org/apache/juneau/microservice/jetty/template/RootResources.java
+++ 
b/juneau-microservice/juneau-my-jetty-microservice/src/main/java/org/apache/juneau/microservice/jetty/template/RootResources.java
@@ -15,7 +15,6 @@ package org.apache.juneau.microservice.jetty.template;
 import org.apache.juneau.html.annotation.HtmlDocConfig;
 import org.apache.juneau.microservice.jetty.resources.DebugResource;
 import org.apache.juneau.microservice.resources.ConfigResource;
-import org.apache.juneau.microservice.resources.LogsResource;
 import org.apache.juneau.rest.annotation.*;
 import org.apache.juneau.rest.servlet.BasicRestServletGroup;
 import org.apache.juneau.rest.widget.ContentTypeMenuItem;
@@ -38,7 +37,6 @@ import org.apache.juneau.rest.widget.ThemeMenuItem;
        children={
                HelloWorldResource.class,
                ConfigResource.class,
-               LogsResource.class,
                DebugResource.class
        }
 )
diff --git 
a/juneau-microservice/juneau-my-springboot-microservice/src/main/java/org/apache/juneau/microservice/springboot/template/RootResources.java
 
b/juneau-microservice/juneau-my-springboot-microservice/src/main/java/org/apache/juneau/microservice/springboot/template/RootResources.java
index 051ab0b4c..6122e8ba2 100644
--- 
a/juneau-microservice/juneau-my-springboot-microservice/src/main/java/org/apache/juneau/microservice/springboot/template/RootResources.java
+++ 
b/juneau-microservice/juneau-my-springboot-microservice/src/main/java/org/apache/juneau/microservice/springboot/template/RootResources.java
@@ -36,8 +36,7 @@ import org.apache.juneau.serializer.annotation.*;
        description="Example of a router resource page.",
        children={
                HelloWorldResource.class,
-               ConfigResource.class,
-               LogsResource.class
+               ConfigResource.class
        }
 )
 @HtmlDocConfig(
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
index 79012cf3a..53d594b7b 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
@@ -4202,12 +4202,12 @@ public class RestContext extends Context {
 
                                RestContext cc = cb.init(so).build();
 
-                               MethodInfo mi = ClassInfo.of(o).getPublicMethod(
+                               MethodInfo mi = 
ClassInfo.of(so.get()).getMethod(
                                        x -> x.hasName("setContext")
                                        && x.hasParamTypes(RestContext.class)
                                );
                                if (mi != null)
-                                       mi.accessible().invoke(o, cc);
+                                       mi.accessible().invoke(so.get(), cc);
 
                                v.get().add(cc);
                        }
diff --git a/pom.xml b/pom.xml
index ef445293d..d35bd162f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -187,6 +187,7 @@
                                                <!-- Generated by embedded 
jetty server -->
                                                
<exclude>**/jetty.out.xml</exclude>
                                                <exclude>**/*.log</exclude>
+                                               <exclude>**/*.log.*</exclude>
                                                
                                                <!-- Generated in 
juneau-microservice-template for some reason -->
                                                
<exclude>**/dependency-reduced-pom.xml</exclude>

Reply via email to