Skip to content

Commit

Permalink
Add registries for components
Browse files Browse the repository at this point in the history
  • Loading branch information
agentgt committed Jan 10, 2024
1 parent 72429ea commit 56dc355
Show file tree
Hide file tree
Showing 17 changed files with 458 additions and 120 deletions.
33 changes: 30 additions & 3 deletions core/src/main/java/io/jstach/rainbowgum/LogAppender.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package io.jstach.rainbowgum;

import java.net.URI;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Function;
Expand All @@ -20,6 +19,26 @@
*/
public interface LogAppender extends LogLifecycle, LogEventConsumer {

/**
* Default Console appender name.
*/
static final String CONSOLE_APPENDER_NAME = "console";

/**
* Default output file appender name.
*/
static final String FILE_APPENDER_NAME = "file";

/**
* Output appender property.
*/
static final String APPENDER_OUTPUT_PROPERTY = LogProperties.APPENDER_PREFIX + "output";

/**
* Encoder appender property.
*/
static final String APPENDER_ENCODER_PROPERTY = LogProperties.APPENDER_PREFIX + "encoder";

/**
* Batch of events. <strong>DO NOT MODIFY THE ARRAY</strong>. Do not use the
* <code>length</code> of the passed in array but instead use <code>count</code>
Expand Down Expand Up @@ -93,9 +112,19 @@ public static final class Builder {

protected @Nullable LogEncoder encoder;

// private final String name;

private Builder() {
}

//// /**
//// * Name of the appender.
//// * @return name.
//// */
//// public String name() {
//// return this.name;
// }

/**
* Sets output. If not set defaults to {@link LogOutput#ofStandardOut()}.
* @param output output.
Expand Down Expand Up @@ -340,8 +369,6 @@ class DefaultLogAppender extends AbstractLogAppender implements ThreadSafeLogApp
return new LockingLogAppender(appender);
};

static final Property<URI> fileProperty = Property.builder().map(URI::new).build(LogProperties.FILE_PROPERTY);

protected final ReentrantLock lock = new ReentrantLock();

public DefaultLogAppender(LogOutput output, LogEncoder encoder) {
Expand Down
142 changes: 142 additions & 0 deletions core/src/main/java/io/jstach/rainbowgum/LogAppenderRegistry.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
package io.jstach.rainbowgum;

import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

import org.eclipse.jdt.annotation.Nullable;

import io.jstach.rainbowgum.LogAppender.AppenderProvider;
import io.jstach.rainbowgum.LogProperties.Property;

/**
* Register appenders by name.
*/
public sealed interface LogAppenderRegistry permits DefaultAppenderRegistry {

/**
* Finds an appender by name.
* @param name name of the appender.
* @return appender provider to be used for creating the appender.
*/
Optional<AppenderProvider> appender(String name);

/**
* Registers an appender provider by name.
* @param name of the appender.
* @param appenderProvider factory to be used for creating appenders.
*/
void register(String name, AppenderProvider appenderProvider);

/**
* Creates a log appender registry.
* @return appender registry.
*/
public static LogAppenderRegistry of() {
return new DefaultAppenderRegistry();
}

}

final class DefaultAppenderRegistry implements LogAppenderRegistry {

private final Map<String, AppenderProvider> providers = new ConcurrentHashMap<>();

static final Property<URI> fileProperty = Property.builder().toURI().build(LogProperties.FILE_PROPERTY);

static final Property<List<String>> appendersProperty = Property.builder()
.map(LogProperties::parseList)
.orElse(List.of())
.build(LogProperties.APPENDERS_PROPERTY);

static List<LogAppender> defaultAppenders(LogConfig config) {
List<LogAppender> appenders = new ArrayList<>();
fileAppender(config).ifPresent(appenders::add);
List<String> appenderNames = appendersProperty.get(config.properties()).value(List.of());

for (String appenderName : appenderNames) {
var outputProperty = outputProperty(LogAppender.APPENDER_OUTPUT_PROPERTY, appenderName, config);
var encoderProperty = encoderProperty(LogAppender.APPENDER_ENCODER_PROPERTY, appenderName, config);
appenders.add(appender(appenderName, outputProperty, encoderProperty, config));
}
if (appenders.isEmpty()) {
var consoleAppender = defaultConsoleAppender(config);
appenders.add(consoleAppender);
}
return appenders;
}

private static LogAppender defaultConsoleAppender(LogConfig config) {
var consoleAppender = LogAppender.builder().output(LogOutput.ofStandardOut()).build().provide(config);
return consoleAppender;
}

static Optional<LogAppender> fileAppender(LogConfig config) {
String name = LogAppender.FILE_APPENDER_NAME;
var outputProperty = outputProperty(LogAppender.APPENDER_OUTPUT_PROPERTY, name, config);
var encoderProperty = encoderProperty(LogAppender.APPENDER_ENCODER_PROPERTY, name, config);
return fileProperty //
.map(u -> appender(name, outputProperty, encoderProperty, config))
.get(config.properties())
.optional();
}

static LogAppender appender( //
String name, Property<LogOutput> outputProperty, Property<LogEncoder> encoderProperty, LogConfig config) {
var appenderRegistry = config.appenderRegistry();
var appender = appenderRegistry.appender(name).map(a -> a.provide(config)).orElse(null);
if (appender != null) {
return appender;
}
var builder = LogAppender.builder();
LogOutput output = outputProperty.get(config.properties()).valueOrNull();
if (output != null) {
builder.output(output);
}
LogEncoder encoder = encoderProperty.get(config.properties()).valueOrNull();
if (encoder != null) {
builder.encoder(encoder);
}
return builder.build().provide(config);

}

private static @Nullable LogOutput outputForAppender(String propertyName, String name, LogConfig config) {
LogOutput output = Property.builder() //
.toURI() //
.map(u -> config.outputRegistry().output(u, name, config.properties())) //
.buildWithName(propertyName, name) //
.get(config.properties()) //
.valueOrNull();
return output;
}

private static Property<LogOutput> outputProperty(String propertyName, String name, LogConfig config) {
return Property.builder() //
.toURI() //
.map(u -> config.outputRegistry().output(u, name, config.properties())) //
.buildWithName(propertyName, name);
}

private static Property<LogEncoder> encoderProperty(String propertyName, String name, LogConfig config) {
return Property.builder() //
.toURI() //
.map(u -> config.encoderRegistry().provide(u, name, config.properties())) //
.buildWithName(propertyName, name);
}

@Override
public Optional<AppenderProvider> appender(String name) {
return Optional.ofNullable(providers.get(name));
}

@Override
public void register(String name, AppenderProvider appenderProvider) {
providers.put(name, appenderProvider);

}

}
44 changes: 30 additions & 14 deletions core/src/main/java/io/jstach/rainbowgum/LogConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@

import io.jstach.rainbowgum.LevelResolver.LevelConfig;
import io.jstach.rainbowgum.LogConfig.ChangePublisher;
import io.jstach.rainbowgum.LogProperties.Property;
import io.jstach.rainbowgum.LogProperties.PropertyGetter;
import io.jstach.rainbowgum.LogProperties.PropertyValue;

/**
* The configuration of a RainbowGum. In some other logging implementations this is called
Expand All @@ -26,16 +24,6 @@ public sealed interface LogConfig {
*/
public LogProperties properties();

/**
* Gets a property value from the properties.
* @param <T> property type
* @param property property to look up.
* @return property value nevern <code>null</code>.
*/
default <T> PropertyValue<T> get(Property<T> property) {
return properties().property(property);
}

/**
* Level resolver for resolving levels from logger names.
* @return level resolver.
Expand All @@ -54,6 +42,18 @@ default <T> PropertyValue<T> get(Property<T> property) {
*/
public LogOutputRegistry outputRegistry();

/**
* Provides appenders by name.
* @return appender registry.
*/
public LogAppenderRegistry appenderRegistry();

/**
* Provides encoders by name.
* @return encoder registry.
*/
public LogEncoderRegistry encoderRegistry();

/**
* Finds an output from a URI.
* @param uri uri.
Expand Down Expand Up @@ -102,7 +102,7 @@ public static Builder builder() {
* initialization process.
* @return registry.
*/
public ServiceRegistry registry();
public ServiceRegistry serviceRegistry();

/**
* Config Change Publisher.
Expand Down Expand Up @@ -230,6 +230,10 @@ final class DefaultLogConfig implements LogConfig {

private final LogFormatterRegistry formatterRegistry;

private final LogAppenderRegistry appenderRegistry;

private final LogEncoderRegistry encoderRegistry;

public DefaultLogConfig(ServiceRegistry registry, LogProperties properties) {
super();
this.registry = registry;
Expand All @@ -243,6 +247,8 @@ protected LogConfig _config() {
};
this.outputRegistry = LogOutputRegistry.of();
this.formatterRegistry = LogFormatterRegistry.of();
this.appenderRegistry = LogAppenderRegistry.of();
this.encoderRegistry = LogEncoderRegistry.of();
}

@Override
Expand All @@ -256,7 +262,7 @@ public LevelConfig levelResolver() {
}

@Override
public ServiceRegistry registry() {
public ServiceRegistry serviceRegistry() {
return this.registry;
}

Expand All @@ -275,4 +281,14 @@ public LogFormatterRegistry formatterRegistry() {
return this.formatterRegistry;
}

@Override
public LogAppenderRegistry appenderRegistry() {
return this.appenderRegistry;
}

@Override
public LogEncoderRegistry encoderRegistry() {
return this.encoderRegistry;
}

}
19 changes: 19 additions & 0 deletions core/src/main/java/io/jstach/rainbowgum/LogEncoder.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.jstach.rainbowgum;

import java.io.IOException;
import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
Expand Down Expand Up @@ -68,6 +70,23 @@ public static LogEncoder of(LogFormatter formatter) {
return new FormatterEncoder(formatter);
}

/**
* Finds output based on URI.
*/
public interface EncoderProvider {

/**
* Loads an encoder from a URI.
* @param uri uri.
* @param name name of encoder.
* @param properties key value config.
* @return output.
* @see LogProperties#of(URI)
*/
LogEncoder provide(URI uri, String name, LogProperties properties);

}

/**
* Encoders buffer.
*/
Expand Down
Loading

0 comments on commit 56dc355

Please sign in to comment.