-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
207 additions
and
171 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,150 +1,17 @@ | ||
package io.jstach.rainbowgum; | ||
|
||
import java.net.URI; | ||
import java.util.EnumMap; | ||
import java.util.List; | ||
import java.util.concurrent.CopyOnWriteArrayList; | ||
import java.util.concurrent.atomic.AtomicBoolean; | ||
import java.util.concurrent.locks.ReentrantReadWriteLock; | ||
import java.util.function.Function; | ||
import java.util.function.Supplier; | ||
import java.util.stream.Stream; | ||
|
||
import org.eclipse.jdt.annotation.Nullable; | ||
|
||
import io.jstach.rainbowgum.LogAppender.ThreadSafeLogAppender; | ||
import io.jstach.rainbowgum.LogOutput.OutputType; | ||
import io.jstach.rainbowgum.LogProperties.Property; | ||
import io.jstach.rainbowgum.format.StandardEventFormatter; | ||
import io.jstach.rainbowgum.publisher.BlockingQueueAsyncLogPublisher; | ||
|
||
/** | ||
* Static defaults that should probably be in the config class. | ||
* | ||
* @author agentgt | ||
*/ | ||
public class Defaults { | ||
final class Defaults { | ||
|
||
static final String SHUTDOWN = "#SHUTDOWN#"; | ||
|
||
/** | ||
* Default async buffer size. | ||
*/ | ||
public static final int ASYNC_BUFFER_SIZE = 1024; | ||
|
||
private static final ReentrantReadWriteLock staticLock = new ReentrantReadWriteLock(); | ||
|
||
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); | ||
|
||
private static CopyOnWriteArrayList<AutoCloseable> shutdownHooks = new CopyOnWriteArrayList<>(); | ||
|
||
// we do not need the newer VarHandle because there is only one of these guys | ||
private static AtomicBoolean shutdownHookRegistered = new AtomicBoolean(false); | ||
|
||
private final EnumMap<OutputType, Supplier<? extends LogFormatter>> formatters = new EnumMap<>(OutputType.class); | ||
|
||
private final LogProperties properties; | ||
|
||
private static final Property<Boolean> defaultsAppenderBufferProperty = Property.builder() | ||
.map(s -> Boolean.parseBoolean(s)) | ||
.orElse(false) | ||
.build(LogProperties.concatKey("defaults.appender.buffer")); | ||
|
||
static final Property<URI> fileProperty = Property.builder().map(URI::new).build(LogProperties.FILE_PROPERTY); | ||
|
||
static final Property<List<String>> outputProperty = Property.builder() | ||
.map(p -> Stream.of(p.split(",")).filter(s -> !s.trim().isEmpty()).toList()) | ||
.build(LogProperties.OUTPUT_PROPERTY); | ||
|
||
Defaults(LogProperties logProperties) { | ||
this.properties = logProperties; | ||
} | ||
|
||
static Function<LogAppender, ThreadSafeLogAppender> threadSafeAppender = (appender) -> { | ||
return new LockingLogAppender(appender); | ||
}; | ||
|
||
LogPublisher.AsyncLogPublisher asyncPublisher(List<? extends LogAppender> appenders, int bufferSize) { | ||
return BlockingQueueAsyncLogPublisher.of(appenders, bufferSize); | ||
} | ||
|
||
LogAppender logAppender(LogOutput output, @Nullable LogEncoder encoder) { | ||
if (encoder == null) { | ||
encoder = LogEncoder.of(formatterForOutputType(output.type())); | ||
} | ||
; | ||
return defaultsAppenderBufferProperty.get(properties).value() ? new BufferLogAppender(output, encoder) | ||
: new DefaultLogAppender(output, encoder); | ||
} | ||
// static final Property<URI> fileProperty = | ||
// Property.builder().map(URI::new).build(LogProperties.FILE_PROPERTY); | ||
|
||
static final String NEW_LINE = "\n"; | ||
|
||
/** | ||
* Associates a default formatter with a specific output type | ||
* @param outputType output type to use for finding best default formatter. | ||
* @return formatter for output type. | ||
*/ | ||
public LogFormatter formatterForOutputType(OutputType outputType) { | ||
lock.readLock().lock(); | ||
try { | ||
var formatter = formatters.get(outputType); | ||
if (formatter == null) { | ||
return StandardEventFormatter.builder().build(); | ||
} | ||
return formatter.get(); | ||
} | ||
finally { | ||
lock.readLock().unlock(); | ||
} | ||
} | ||
|
||
/** | ||
* Sets a default formatter for a specific output type. | ||
* @param outputType output type. | ||
* @param formatter formatter. | ||
*/ | ||
public void setFormatterForOutputType(OutputType outputType, Supplier<? extends LogFormatter> formatter) { | ||
lock.writeLock().lock(); | ||
try { | ||
formatters.put(outputType, formatter); | ||
} | ||
finally { | ||
lock.writeLock().unlock(); | ||
} | ||
} | ||
|
||
static void addShutdownHook(AutoCloseable hook) { | ||
staticLock.writeLock().lock(); | ||
try { | ||
if (shutdownHookRegistered.compareAndSet(false, true)) { | ||
var thread = new Thread(() -> { | ||
runShutdownHooks(); | ||
}); | ||
thread.setName("rainbowgum-shutdown"); | ||
Runtime.getRuntime().addShutdownHook(thread); | ||
} | ||
shutdownHooks.add(hook); | ||
} | ||
finally { | ||
staticLock.writeLock().unlock(); | ||
} | ||
} | ||
|
||
private static void runShutdownHooks() { | ||
/* | ||
* We do not lock here since we are in the shutdown thread luckily shutdownHooks | ||
* is thread safe | ||
*/ | ||
for (var hook : shutdownHooks) { | ||
try { | ||
hook.close(); | ||
} | ||
catch (Exception e) { | ||
MetaLog.error(Defaults.class, e); | ||
} | ||
} | ||
// Help the GC or whatever final cleanup is going on | ||
shutdownHooks.clear(); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
79 changes: 79 additions & 0 deletions
79
core/src/main/java/io/jstach/rainbowgum/LogFormatterRegistry.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package io.jstach.rainbowgum; | ||
|
||
import java.util.EnumMap; | ||
import java.util.concurrent.locks.ReentrantReadWriteLock; | ||
import java.util.function.Supplier; | ||
|
||
import io.jstach.rainbowgum.LogOutput.OutputType; | ||
import io.jstach.rainbowgum.format.StandardEventFormatter; | ||
|
||
/** | ||
* Formatters that are registered based on output type. | ||
*/ | ||
public sealed interface LogFormatterRegistry permits DefaultLogFormatterRegistry { | ||
|
||
/** | ||
* Creates a log formatter registry. | ||
* @return new created log formatter registry. | ||
*/ | ||
public static LogFormatterRegistry of() { | ||
return new DefaultLogFormatterRegistry(); | ||
} | ||
|
||
/** | ||
* Associates a default formatter with a specific output type | ||
* @param outputType output type to use for finding best default formatter. | ||
* @return formatter for output type. | ||
*/ | ||
public LogFormatter formatterForOutputType(OutputType outputType); | ||
|
||
/** | ||
* Sets a default formatter for a specific output type. | ||
* @param outputType output type. | ||
* @param formatter formatter. | ||
*/ | ||
public void setFormatterForOutputType(OutputType outputType, Supplier<? extends LogFormatter> formatter); | ||
|
||
} | ||
|
||
final class DefaultLogFormatterRegistry implements LogFormatterRegistry { | ||
|
||
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); | ||
|
||
private final EnumMap<OutputType, Supplier<? extends LogFormatter>> formatters = new EnumMap<>(OutputType.class); | ||
|
||
/** | ||
* Associates a default formatter with a specific output type | ||
* @param outputType output type to use for finding best default formatter. | ||
* @return formatter for output type. | ||
*/ | ||
public LogFormatter formatterForOutputType(OutputType outputType) { | ||
lock.readLock().lock(); | ||
try { | ||
var formatter = formatters.get(outputType); | ||
if (formatter == null) { | ||
return StandardEventFormatter.builder().build(); | ||
} | ||
return formatter.get(); | ||
} | ||
finally { | ||
lock.readLock().unlock(); | ||
} | ||
} | ||
|
||
/** | ||
* Sets a default formatter for a specific output type. | ||
* @param outputType output type. | ||
* @param formatter formatter. | ||
*/ | ||
public void setFormatterForOutputType(OutputType outputType, Supplier<? extends LogFormatter> formatter) { | ||
lock.writeLock().lock(); | ||
try { | ||
formatters.put(outputType, formatter); | ||
} | ||
finally { | ||
lock.writeLock().unlock(); | ||
} | ||
} | ||
|
||
} |
Oops, something went wrong.