From bd6c0cd8acac8ff6820ae051a1ab5d7ce3e324a3 Mon Sep 17 00:00:00 2001 From: "David M. Lloyd" Date: Fri, 10 Nov 2023 14:45:57 -0600 Subject: [PATCH] Add support for long thread IDs --- .../org/jboss/logmanager/ExtLogRecord.java | 83 ++++++++++++++++++- .../jboss/logmanager/WrappedExtLogRecord.java | 52 ++++++++++++ .../logmanager/formatters/Formatters.java | 2 +- 3 files changed, 135 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/jboss/logmanager/ExtLogRecord.java b/src/main/java/org/jboss/logmanager/ExtLogRecord.java index 56f69684..310a1e0c 100644 --- a/src/main/java/org/jboss/logmanager/ExtLogRecord.java +++ b/src/main/java/org/jboss/logmanager/ExtLogRecord.java @@ -22,6 +22,10 @@ import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.lang.reflect.UndeclaredThrowableException; import java.text.MessageFormat; import java.util.Map; import java.util.MissingResourceException; @@ -38,6 +42,24 @@ public class ExtLogRecord extends LogRecord { private static final long serialVersionUID = -9174374711278052369L; + private static final MethodHandle superGetLongThreadID; + private static final MethodHandle superSetLongThreadID; + + static { + MethodHandle getter = null, setter = null; + try { + MethodHandles.Lookup pl = MethodHandles.lookup(); + //noinspection JavaLangInvokeHandleSignature + getter = pl.findSpecial(LogRecord.class, "getLongThreadID", MethodType.methodType(long.class), ExtLogRecord.class); + //noinspection JavaLangInvokeHandleSignature + setter = pl.findSpecial(LogRecord.class, "setLongThreadID", MethodType.methodType(LogRecord.class, long.class), + ExtLogRecord.class); + } catch (NoSuchMethodException | IllegalAccessException ignored) { + } + superGetLongThreadID = getter; + superSetLongThreadID = setter; + } + /** * The format style to use. */ @@ -83,6 +105,7 @@ public ExtLogRecord(final java.util.logging.Level level, final String msg, final this.loggerClassName = loggerClassName; ndc = NDC.get(); threadName = Thread.currentThread().getName(); + longThreadID = Thread.currentThread().getId(); // todo: threadId() on 19+ hostName = HostName.getQualifiedHostName(); processName = io.smallrye.common.os.Process.getProcessName(); processId = io.smallrye.common.os.Process.getProcessId(); @@ -102,7 +125,6 @@ public ExtLogRecord(final ExtLogRecord original) { setResourceBundle(original.getResourceBundle()); setResourceBundleName(original.getResourceBundleName()); setSequenceNumber(original.getSequenceNumber()); - setThreadID(original.getThreadID()); setThrown(original.getThrown()); if (!original.calculateCaller) { setSourceClassName(original.getSourceClassName()); @@ -112,6 +134,7 @@ public ExtLogRecord(final ExtLogRecord original) { sourceModuleName = original.sourceModuleName; sourceModuleVersion = original.sourceModuleVersion; } + setLongThreadID(original.getLongThreadID()); formatStyle = original.formatStyle; marker = original.marker; mdcCopy = original.mdcCopy; @@ -155,6 +178,7 @@ public static ExtLogRecord wrap(LogRecord rec) { private String sourceModuleName; private String sourceModuleVersion; private Object marker; + private long longThreadID; private void writeObject(ObjectOutputStream oos) throws IOException { copyAll(); @@ -176,6 +200,15 @@ private void readObject(ObjectInputStream ois) throws IOException, ClassNotFound sourceModuleName = (String) fields.get("sourceModuleName", null); sourceModuleVersion = (String) fields.get("sourceModuleVersion", null); marker = fields.get("marker", null); + long id = fields.get("longThreadID", superGetLongThreadID()); + // replicate the 17+ behavior + if (id >= 0 && id <= Integer.MAX_VALUE) { + super.setThreadID((int) id); + } else { + int hash = Long.hashCode(id); + super.setThreadID(hash < 0 ? hash : (-1 - hash)); + } + longThreadID = id; } /** @@ -631,4 +664,52 @@ public void setMarker(Object marker) { public Object getMarker() { return marker; } + + @Override + public void setThreadID(final int threadID) { + super.setThreadID(threadID); + this.longThreadID = threadID; + } + + long superGetLongThreadID() { + try { + return superGetLongThreadID == null ? getThreadID() : (long) superGetLongThreadID.invokeExact(this); + } catch (RuntimeException | Error e) { + throw e; + } catch (Throwable e) { + throw new UndeclaredThrowableException(e); + } + } + + // @Override (17+) + public long getLongThreadID() { + return longThreadID; + } + + void superSetLongThreadID(final long id) { + if (superSetLongThreadID != null) { + try { + superSetLongThreadID.invokeExact(this, id); + } catch (RuntimeException | Error e) { + throw e; + } catch (Throwable e) { + throw new UndeclaredThrowableException(e); + } + } else { + // replicate the 17+ behavior + if (id >= 0 && id <= Integer.MAX_VALUE) { + super.setThreadID((int) id); + } else { + int hash = Long.hashCode(id); + super.setThreadID(hash < 0 ? hash : (-1 - hash)); + } + } + } + + // @Override (17+) + public ExtLogRecord setLongThreadID(final long id) { + superSetLongThreadID(id); + this.longThreadID = id; + return this; + } } diff --git a/src/main/java/org/jboss/logmanager/WrappedExtLogRecord.java b/src/main/java/org/jboss/logmanager/WrappedExtLogRecord.java index 7bf00b23..d6841e6f 100644 --- a/src/main/java/org/jboss/logmanager/WrappedExtLogRecord.java +++ b/src/main/java/org/jboss/logmanager/WrappedExtLogRecord.java @@ -19,6 +19,10 @@ package org.jboss.logmanager; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.lang.reflect.UndeclaredThrowableException; import java.time.Instant; import java.util.ResourceBundle; import java.util.logging.Level; @@ -29,12 +33,33 @@ class WrappedExtLogRecord extends ExtLogRecord { private static final long serialVersionUID = 980830752574061944L; private static final String LOGGER_CLASS_NAME = java.util.logging.Logger.class.getName(); + private static final MethodHandle getLongThreadID; + private static final MethodHandle setLongThreadID; + + static { + MethodHandle getter = null, setter = null; + try { + MethodHandles.Lookup pl = MethodHandles.publicLookup(); + //noinspection JavaLangInvokeHandleSignature + getter = pl.findVirtual(LogRecord.class, "getLongThreadID", MethodType.methodType(long.class)); + //noinspection JavaLangInvokeHandleSignature + setter = pl.findVirtual(LogRecord.class, "setLongThreadID", MethodType.methodType(LogRecord.class, long.class)); + } catch (NoSuchMethodException | IllegalAccessException ignored) { + } + getLongThreadID = getter; + setLongThreadID = setter; + } + private transient final LogRecord orig; private transient boolean resolved; WrappedExtLogRecord(final LogRecord orig) { super(orig.getLevel(), orig.getMessage(), LOGGER_CLASS_NAME); this.orig = orig; + if (getLongThreadID == null) { + // we have to initialize our long thread ID field because this JDK doesn't have one + setLongThreadID(getThreadID()); + } } public String getLoggerName() { @@ -176,9 +201,36 @@ public int getThreadID() { } public void setThreadID(final int threadID) { + super.setThreadID(threadID); orig.setThreadID(threadID); } + // @Override (17+) + public long getLongThreadID() { + try { + return getLongThreadID == null ? super.getLongThreadID() : (long) getLongThreadID.invokeExact(orig); + } catch (RuntimeException | Error e) { + throw e; + } catch (Throwable e) { + throw new UndeclaredThrowableException(e); + } + } + + // @Override (17+) + public ExtLogRecord setLongThreadID(final long id) { + super.setLongThreadID(id); + if (setLongThreadID != null) { + try { + setLongThreadID.invokeExact(orig, id); + } catch (RuntimeException | Error e) { + throw e; + } catch (Throwable e) { + throw new UndeclaredThrowableException(e); + } + } + return this; + } + public long getMillis() { return orig.getMillis(); } diff --git a/src/main/java/org/jboss/logmanager/formatters/Formatters.java b/src/main/java/org/jboss/logmanager/formatters/Formatters.java index 4dcc9a18..499ebec5 100644 --- a/src/main/java/org/jboss/logmanager/formatters/Formatters.java +++ b/src/main/java/org/jboss/logmanager/formatters/Formatters.java @@ -1202,7 +1202,7 @@ public ItemType getItemType() { } public void renderRaw(Formatter formatter, final StringBuilder builder, final ExtLogRecord record) { - builder.append(record.getThreadID()); + builder.append(record.getLongThreadID()); } }; }