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.ClassLoaderDump;
|
||||||
import org.eclipse.jetty.util.component.DumpableAttributes;
|
import org.eclipse.jetty.util.component.DumpableAttributes;
|
||||||
import org.eclipse.jetty.util.component.DumpableCollection;
|
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.Environment;
|
||||||
import org.eclipse.jetty.util.component.Graceful;
|
import org.eclipse.jetty.util.component.Graceful;
|
||||||
import org.eclipse.jetty.util.component.LifeCycle;
|
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)
|
public Server(@Name("threadPool") ThreadPool pool)
|
||||||
{
|
{
|
||||||
this(pool, null, null);
|
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)
|
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.server.internal.HttpConnection;
|
||||||
import org.eclipse.jetty.util.Blocker;
|
import org.eclipse.jetty.util.Blocker;
|
||||||
import org.eclipse.jetty.util.Callback;
|
import org.eclipse.jetty.util.Callback;
|
||||||
|
import org.eclipse.jetty.util.Jetty;
|
||||||
import org.eclipse.jetty.util.component.LifeCycle;
|
import org.eclipse.jetty.util.component.LifeCycle;
|
||||||
import org.eclipse.jetty.util.thread.Invocable;
|
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.AfterEach;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
@ -143,6 +145,26 @@ public class ServerTest
|
||||||
assertThat(response.getContent(), is("Hello"));
|
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()
|
public static Stream<Arguments> completionScenarios()
|
||||||
{
|
{
|
||||||
List<Arguments> arguments = new ArrayList<>();
|
List<Arguments> arguments = new ArrayList<>();
|
||||||
|
|
|
@ -745,10 +745,10 @@ public class ContainerLifeCycle extends AbstractLifeCycle implements Container,
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
dump(System.err, "");
|
Dumpable.dump(this, System.err);
|
||||||
System.err.println(Dumpable.KEY);
|
System.err.println();
|
||||||
}
|
}
|
||||||
catch (IOException e)
|
catch (Throwable e)
|
||||||
{
|
{
|
||||||
LOG.warn("Unable to dump", e);
|
LOG.warn("Unable to dump", e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,8 +14,13 @@
|
||||||
package org.eclipse.jetty.util.component;
|
package org.eclipse.jetty.util.component;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.UncheckedIOException;
|
||||||
import java.lang.reflect.Array;
|
import java.lang.reflect.Array;
|
||||||
import java.nio.file.Path;
|
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.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
@ -23,6 +28,7 @@ import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.util.Jetty;
|
||||||
import org.eclipse.jetty.util.StringUtil;
|
import org.eclipse.jetty.util.StringUtil;
|
||||||
import org.eclipse.jetty.util.TypeUtil;
|
import org.eclipse.jetty.util.TypeUtil;
|
||||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||||
|
@ -31,7 +37,7 @@ import org.eclipse.jetty.util.annotation.ManagedOperation;
|
||||||
@ManagedObject("Dumpable Object")
|
@ManagedObject("Dumpable Object")
|
||||||
public interface Dumpable
|
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")
|
@ManagedOperation(value = "Dump the nested Object state as a String", impact = "INFO")
|
||||||
default String dump()
|
default String dump()
|
||||||
|
@ -50,24 +56,55 @@ public interface Dumpable
|
||||||
void dump(Appendable out, String indent) throws IOException;
|
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
|
* @param dumpable The dumpable to dump
|
||||||
* @return The dumped string
|
* @return The dumped string
|
||||||
|
* @see #dump(Appendable, String)
|
||||||
*/
|
*/
|
||||||
static String dump(Dumpable dumpable)
|
static String dump(Dumpable dumpable)
|
||||||
{
|
{
|
||||||
StringBuilder b = new StringBuilder();
|
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
|
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)
|
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
|
* interface to allow it to refine which of its beans can be
|
||||||
* dumped.
|
* dumped.
|
||||||
*/
|
*/
|
||||||
public interface DumpableContainer extends Dumpable
|
interface DumpableContainer extends Dumpable
|
||||||
{
|
{
|
||||||
default boolean isDumpable(Object o)
|
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.ProcessorUtils;
|
||||||
import org.eclipse.jetty.util.TypeUtil;
|
import org.eclipse.jetty.util.TypeUtil;
|
||||||
import org.eclipse.jetty.util.component.Dumpable;
|
import org.eclipse.jetty.util.component.Dumpable;
|
||||||
import org.eclipse.jetty.util.component.DumpableCollection;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -236,8 +235,12 @@ public class ThreadIdPool<E> implements Dumpable
|
||||||
int capacity = capacity();
|
int capacity = capacity();
|
||||||
List<Object> slots = new ArrayList<>(capacity);
|
List<Object> slots = new ArrayList<>(capacity);
|
||||||
for (int i = 0; i < capacity; i++)
|
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
|
@Override
|
||||||
|
|
|
@ -833,8 +833,7 @@ public class QueuedThreadPoolTest extends AbstractThreadPoolTest
|
||||||
assertThat(count(dump, " - STARTED"), is(3));
|
assertThat(count(dump, " - STARTED"), is(3));
|
||||||
assertThat(dump, containsString(",3<=3<=4,i=1,r=2,"));
|
assertThat(dump, containsString(",3<=3<=4,i=1,r=2,"));
|
||||||
assertThat(dump, containsString("[ReservedThreadExecutor@"));
|
assertThat(dump, containsString("[ReservedThreadExecutor@"));
|
||||||
assertThat(count(dump, "> ReservedThread@"), is(1));
|
assertThat(count(dump, "+> 0: ReservedThread@"), is(1));
|
||||||
assertThat(count(dump, "> null"), is(1));
|
|
||||||
assertThat(count(dump, "QueuedThreadPoolTest.lambda$testDump$"), is(0));
|
assertThat(count(dump, "QueuedThreadPoolTest.lambda$testDump$"), is(0));
|
||||||
|
|
||||||
pool.setDetailedDump(true);
|
pool.setDetailedDump(true);
|
||||||
|
|
|
@ -125,14 +125,12 @@ public class DebugListener extends AbstractLifeCycle implements ServletContextLi
|
||||||
if (_out == null)
|
if (_out == null)
|
||||||
{
|
{
|
||||||
handler.dumpStdErr();
|
handler.dumpStdErr();
|
||||||
System.err.println(Dumpable.KEY);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
handler.dump(_out);
|
Dumpable.dump(handler, _out);
|
||||||
_out.println(Dumpable.KEY);
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -121,14 +121,12 @@ public class DebugListener extends AbstractLifeCycle implements ServletContextLi
|
||||||
if (_out == null)
|
if (_out == null)
|
||||||
{
|
{
|
||||||
handler.dumpStdErr();
|
handler.dumpStdErr();
|
||||||
System.err.println(Dumpable.KEY);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
handler.dump(_out);
|
Dumpable.dump(handler, _out);
|
||||||
_out.println(Dumpable.KEY);
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue