Fix #9177 dump info from Runtime, Jetty.VERSION and System.getProperties
This commit is contained in:
parent
7e36f3c6e9
commit
042582813f
|
@ -54,6 +54,7 @@ import org.eclipse.jetty.util.component.AttributeContainerMap;
|
|||
import org.eclipse.jetty.util.component.ClassLoaderDump;
|
||||
import org.eclipse.jetty.util.component.DumpableAttributes;
|
||||
import org.eclipse.jetty.util.component.DumpableCollection;
|
||||
import org.eclipse.jetty.util.component.DumpableMap;
|
||||
import org.eclipse.jetty.util.component.Environment;
|
||||
import org.eclipse.jetty.util.component.Graceful;
|
||||
import org.eclipse.jetty.util.component.LifeCycle;
|
||||
|
@ -137,6 +138,7 @@ public class Server extends Handler.Wrapper implements Attributes
|
|||
public Server(@Name("threadPool") ThreadPool pool)
|
||||
{
|
||||
this(pool, null, null);
|
||||
installBean(new DumpableMap("System Properties", System.getProperties()));
|
||||
}
|
||||
|
||||
public Server(@Name("threadPool") ThreadPool threadPool, @Name("scheduler") Scheduler scheduler, @Name("bufferPool") ByteBufferPool bufferPool)
|
||||
|
|
|
@ -32,8 +32,10 @@ import org.eclipse.jetty.server.internal.HttpChannelState;
|
|||
import org.eclipse.jetty.server.internal.HttpConnection;
|
||||
import org.eclipse.jetty.util.Blocker;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Jetty;
|
||||
import org.eclipse.jetty.util.component.LifeCycle;
|
||||
import org.eclipse.jetty.util.thread.Invocable;
|
||||
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -143,6 +145,26 @@ public class ServerTest
|
|||
assertThat(response.getContent(), is("Hello"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDump() throws Exception
|
||||
{
|
||||
testSimpleGET();
|
||||
((QueuedThreadPool)(_server.getThreadPool())).tryExecute(() -> {});
|
||||
String dump = _server.dump();
|
||||
assertThat(dump, containsString("oejs.Server@"));
|
||||
assertThat(dump, containsString("QueuedThreadPool"));
|
||||
assertThat(dump, containsString("+= ReservedThreadExecutor@"));
|
||||
assertThat(dump, containsString(".ArrayByteBufferPool@"));
|
||||
assertThat(dump, containsString("+- System Properties size="));
|
||||
assertThat(dump, containsString("+> java.home: "));
|
||||
assertThat(dump, containsString("+> java.runtime.version: "));
|
||||
assertThat(dump, containsString("+= oejsh.ContextHandler@"));
|
||||
assertThat(dump, containsString("+= LocalConnector@"));
|
||||
assertThat(dump, containsString("key: +-"));
|
||||
assertThat(dump, containsString("JVM: "));
|
||||
assertThat(dump, containsString(Jetty.VERSION));
|
||||
}
|
||||
|
||||
public static Stream<Arguments> completionScenarios()
|
||||
{
|
||||
List<Arguments> arguments = new ArrayList<>();
|
||||
|
|
|
@ -745,10 +745,10 @@ public class ContainerLifeCycle extends AbstractLifeCycle implements Container,
|
|||
{
|
||||
try
|
||||
{
|
||||
dump(System.err, "");
|
||||
System.err.println(Dumpable.KEY);
|
||||
Dumpable.dump(this, System.err);
|
||||
System.err.println();
|
||||
}
|
||||
catch (IOException e)
|
||||
catch (Throwable e)
|
||||
{
|
||||
LOG.warn("Unable to dump", e);
|
||||
}
|
||||
|
|
|
@ -14,8 +14,13 @@
|
|||
package org.eclipse.jetty.util.component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.lang.reflect.Array;
|
||||
import java.nio.file.Path;
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
@ -23,6 +28,7 @@ import java.util.Map;
|
|||
import java.util.Objects;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jetty.util.Jetty;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.TypeUtil;
|
||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
|
@ -31,7 +37,7 @@ import org.eclipse.jetty.util.annotation.ManagedOperation;
|
|||
@ManagedObject("Dumpable Object")
|
||||
public interface Dumpable
|
||||
{
|
||||
String KEY = "key: +- bean, += managed, +~ unmanaged, +? auto, +: iterable, +] array, +@ map, +> undefined";
|
||||
String KEY = "key: +- bean, += managed, +~ unmanaged, +? auto, +: iterable, +] array, +@ map, +> undefined\n";
|
||||
|
||||
@ManagedOperation(value = "Dump the nested Object state as a String", impact = "INFO")
|
||||
default String dump()
|
||||
|
@ -50,24 +56,55 @@ public interface Dumpable
|
|||
void dump(Appendable out, String indent) throws IOException;
|
||||
|
||||
/**
|
||||
* Utility method to implement {@link #dump()} by calling {@link #dump(Appendable, String)}
|
||||
* Utility method to dump to a {@link String}
|
||||
*
|
||||
* @param dumpable The dumpable to dump
|
||||
* @return The dumped string
|
||||
* @see #dump(Appendable, String)
|
||||
*/
|
||||
static String dump(Dumpable dumpable)
|
||||
{
|
||||
StringBuilder b = new StringBuilder();
|
||||
dump(dumpable, b);
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to dump to an {@link Appendable}
|
||||
*
|
||||
* @param dumpable The dumpable to dump
|
||||
* @param out The destination of the dump
|
||||
*/
|
||||
static void dump(Dumpable dumpable, Appendable out)
|
||||
{
|
||||
try
|
||||
{
|
||||
dumpable.dump(b, "");
|
||||
dumpable.dump(out, "");
|
||||
|
||||
out.append(KEY);
|
||||
Runtime runtime = Runtime.getRuntime();
|
||||
Instant now = Instant.now();
|
||||
String zone = System.getProperty("user.timezone");
|
||||
out.append("JVM: %s %s %s; OS: %s %s %s; Jetty: %s; CPUs: %d; mem(free/total/max): %,d/%,d/%,d MiB\nUTC: %s; %s: %s".formatted(
|
||||
System.getProperty("java.vm.vendor"),
|
||||
System.getProperty("java.vm.name"),
|
||||
System.getProperty("java.vm.version"),
|
||||
System.getProperty("os.name"),
|
||||
System.getProperty("os.arch"),
|
||||
System.getProperty("os.version"),
|
||||
Jetty.VERSION,
|
||||
runtime.availableProcessors(),
|
||||
runtime.freeMemory() / (1024 * 1024),
|
||||
runtime.totalMemory() / (1024 * 1024),
|
||||
runtime.maxMemory() / (1024 * 1024),
|
||||
DateTimeFormatter.ISO_DATE_TIME.format(now.atOffset(ZoneOffset.UTC)),
|
||||
zone,
|
||||
DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(now.atZone(ZoneId.of(zone)))));
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
b.append(e.toString());
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
b.append(KEY);
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -301,7 +338,7 @@ public interface Dumpable
|
|||
* interface to allow it to refine which of its beans can be
|
||||
* dumped.
|
||||
*/
|
||||
public interface DumpableContainer extends Dumpable
|
||||
interface DumpableContainer extends Dumpable
|
||||
{
|
||||
default boolean isDumpable(Object o)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.util.component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Comparator;
|
||||
import java.util.Map;
|
||||
|
||||
public class DumpableMap implements Dumpable
|
||||
{
|
||||
private final String _name;
|
||||
private final Map<?, ?> _map;
|
||||
|
||||
public DumpableMap(String name, Map<?, ?> map)
|
||||
{
|
||||
_name = name;
|
||||
_map = map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(Appendable out, String indent) throws IOException
|
||||
{
|
||||
Object[] array = _map.entrySet().stream()
|
||||
.sorted(Map.Entry.comparingByKey(Comparator.comparing(String::valueOf)))
|
||||
.map(e -> Dumpable.named(String.valueOf(e.getKey()), e.getValue())).toArray(Object[]::new);
|
||||
Dumpable.dumpObjects(out, indent, _name + " size=" + array.length, array);
|
||||
}
|
||||
}
|
|
@ -25,7 +25,6 @@ import org.eclipse.jetty.util.MemoryUtils;
|
|||
import org.eclipse.jetty.util.ProcessorUtils;
|
||||
import org.eclipse.jetty.util.TypeUtil;
|
||||
import org.eclipse.jetty.util.component.Dumpable;
|
||||
import org.eclipse.jetty.util.component.DumpableCollection;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -236,8 +235,12 @@ public class ThreadIdPool<E> implements Dumpable
|
|||
int capacity = capacity();
|
||||
List<Object> slots = new ArrayList<>(capacity);
|
||||
for (int i = 0; i < capacity; i++)
|
||||
slots.add(_items.get(toSlot(i)));
|
||||
Dumpable.dumpObjects(out, indent, this, new DumpableCollection("items", slots));
|
||||
{
|
||||
E slot = _items.get(toSlot(i));
|
||||
if (slot != null)
|
||||
slots.add(Dumpable.named(Integer.toString(i), slot));
|
||||
}
|
||||
Dumpable.dumpObjects(out, indent, this, slots.toArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -833,8 +833,7 @@ public class QueuedThreadPoolTest extends AbstractThreadPoolTest
|
|||
assertThat(count(dump, " - STARTED"), is(3));
|
||||
assertThat(dump, containsString(",3<=3<=4,i=1,r=2,"));
|
||||
assertThat(dump, containsString("[ReservedThreadExecutor@"));
|
||||
assertThat(count(dump, "> ReservedThread@"), is(1));
|
||||
assertThat(count(dump, "> null"), is(1));
|
||||
assertThat(count(dump, "+> 0: ReservedThread@"), is(1));
|
||||
assertThat(count(dump, "QueuedThreadPoolTest.lambda$testDump$"), is(0));
|
||||
|
||||
pool.setDetailedDump(true);
|
||||
|
|
|
@ -125,14 +125,12 @@ public class DebugListener extends AbstractLifeCycle implements ServletContextLi
|
|||
if (_out == null)
|
||||
{
|
||||
handler.dumpStdErr();
|
||||
System.err.println(Dumpable.KEY);
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
handler.dump(_out);
|
||||
_out.println(Dumpable.KEY);
|
||||
Dumpable.dump(handler, _out);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
|
|
@ -121,14 +121,12 @@ public class DebugListener extends AbstractLifeCycle implements ServletContextLi
|
|||
if (_out == null)
|
||||
{
|
||||
handler.dumpStdErr();
|
||||
System.err.println(Dumpable.KEY);
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
handler.dump(_out);
|
||||
_out.println(Dumpable.KEY);
|
||||
Dumpable.dump(handler, _out);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue