Skip to content

Commit

Permalink
Fix up configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
agentgt committed Jan 11, 2024
1 parent d30ca38 commit a8e5c70
Show file tree
Hide file tree
Showing 13 changed files with 534 additions and 92 deletions.
56 changes: 22 additions & 34 deletions core/src/main/java/io/jstach/rainbowgum/LogAppender.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import io.jstach.rainbowgum.LogAppender.AbstractLogAppender;
import io.jstach.rainbowgum.LogAppender.ThreadSafeLogAppender;
import io.jstach.rainbowgum.LogEncoder.Buffer;
import io.jstach.rainbowgum.LogProperties.Property;

/**
* Appenders are guaranteed to be written synchronously much like an actor in actor
Expand Down Expand Up @@ -68,20 +67,22 @@ public interface AppenderProvider {

/**
* Creates a builder to create an appender provider.
* @param name name of appender.
* @return builder.
*/
public static Builder builder() {
return LogAppender.builder();
public static Builder builder(String name) {
return LogAppender.builder(name);
}

}

/**
* Creates a builder.
* @param name appender name.
* @return builder.
*/
public static Builder builder() {
return new Builder();
public static Builder builder(String name) {
return new Builder(name);
}

/**
Expand All @@ -108,22 +109,23 @@ public static LogAppender of(List<? extends LogAppender> appenders) {
*/
public static final class Builder {

protected LogOutput output = LogOutput.ofStandardOut();
protected @Nullable LogOutput output;

protected @Nullable LogEncoder encoder;

// private final String name;
private final String name;

private Builder() {
private Builder(String name) {
this.name = name;
}

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

/**
* Sets output. If not set defaults to {@link LogOutput#ofStandardOut()}.
Expand Down Expand Up @@ -172,29 +174,15 @@ public Builder encoder(LogEncoder encoder) {
* @return an appender factory.
*/
public AppenderProvider build() {
var output = this.output;
var encoder = this.encoder;
/*
* We need to capture parameters since appender creation needs to be lazy.
*/
AppenderConfig a = new AppenderConfig(name, output, encoder);
return config -> {
return logAppender(config, output, encoder);
return DefaultAppenderRegistry.appender(a, config);
};
}

private static final Property<Boolean> defaultsAppenderBufferProperty = Property.builder()
.map(s -> Boolean.parseBoolean(s))
.orElse(false)
.build(LogProperties.concatKey("defaults.appender.buffer"));

private static LogAppender logAppender(LogConfig config, LogOutput output, @Nullable LogEncoder encoder) {
var formatterRegistry = config.formatterRegistry();
var properties = config.properties();
if (encoder == null) {
encoder = LogEncoder.of(formatterRegistry.formatterForOutputType(output.type()));
}

return defaultsAppenderBufferProperty.get(properties).value() ? new BufferLogAppender(output, encoder)
: new DefaultLogAppender(output, encoder);
}

}

@Override
Expand Down
101 changes: 85 additions & 16 deletions core/src/main/java/io/jstach/rainbowgum/LogAppenderRegistry.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,33 @@ public static LogAppenderRegistry of() {

}

record AppenderConfig(String name, @Nullable LogOutput output, @Nullable LogEncoder encoder) {

AppenderConfig {
validateName(name);
}

private static String validateName(String name) {
if (name.isBlank()) {
throw new IllegalStateException("Appender name cannot be null. name=" + name);
}
if (name.contains(" ") || name.contains("\t") || name.contains("\n") || name.contains("\r")) {
throw new IllegalStateException("Appender name cannot have whitespace");
}
if (name.contains(LogProperties.SEP)) {
throw new IllegalStateException("Appender name cannot have '" + LogProperties.SEP + "'");
}
return name;
}
}

final class DefaultAppenderRegistry implements LogAppenderRegistry {

/*
* The shit in here is a mess because auto configuration of appenders based on
* properties is complicated particularly because we want to support Spring Boots
* configuration OOB.
*/
private final Map<String, AppenderProvider> providers = new ConcurrentHashMap<>();

static final Property<URI> fileProperty = Property.builder().toURI().build(LogProperties.FILE_PROPERTY);
Expand All @@ -58,9 +83,7 @@ static List<LogAppender> defaultAppenders(LogConfig config) {
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));
appenders.add(appender(appenderName, config));
}
if (appenders.isEmpty()) {
var consoleAppender = defaultConsoleAppender(config);
Expand All @@ -70,7 +93,10 @@ static List<LogAppender> defaultAppenders(LogConfig config) {
}

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

Expand All @@ -79,28 +105,71 @@ static Optional<LogAppender> fileAppender(LogConfig config) {
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))
.map(u -> appender(name, config, outputProperty, encoderProperty))
.get(config.properties())
.optional();
}

private static final Property<Boolean> defaultsAppenderBufferProperty = Property.builder()
.map(s -> Boolean.parseBoolean(s))
.orElse(false)
.build(LogProperties.concatKey("defaults.appender.buffer"));

static LogAppender appender( //
String name, LogConfig config) {
var builder = new AppenderConfig(name, null, null);
var outputProperty = outputProperty(LogAppender.APPENDER_OUTPUT_PROPERTY, name, config);
var encoderProperty = encoderProperty(LogAppender.APPENDER_ENCODER_PROPERTY, name, config);
return appender(builder, config, outputProperty, encoderProperty);
}

static LogAppender appender( //
AppenderConfig appenderConfig, //
LogConfig config) {
String name = appenderConfig.name();
var outputProperty = outputProperty(LogAppender.APPENDER_OUTPUT_PROPERTY, name, config);
var encoderProperty = encoderProperty(LogAppender.APPENDER_ENCODER_PROPERTY, name, config);
return appender(appenderConfig, config, outputProperty, encoderProperty);
}

static LogAppender appender( //
String name, Property<LogOutput> outputProperty, Property<LogEncoder> encoderProperty, LogConfig config) {
AppenderConfig builder, //
LogConfig config, //
Property<LogOutput> outputProperty, Property<LogEncoder> encoderProperty) {

@Nullable
LogOutput output = builder.output();
@Nullable
LogEncoder encoder = builder.encoder();
var properties = config.properties();

if (output == null) {
output = outputProperty.get(properties).value();
}

if (encoder == null) {
var _output = output;
encoder = encoderProperty.get(properties).value(() -> {
var formatterRegistry = config.formatterRegistry();
return LogEncoder.of(formatterRegistry.formatterForOutputType(_output.type()));
});
}

return defaultsAppenderBufferProperty.get(properties).value() ? new BufferLogAppender(output, encoder)
: new DefaultLogAppender(output, encoder);
}

static LogAppender appender( //
String name, //
LogConfig config, //
Property<LogOutput> outputProperty, Property<LogEncoder> encoderProperty) {
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);
var builder = new AppenderConfig(name, null, null);
return appender(builder, config, outputProperty, encoderProperty);

}

Expand Down
1 change: 0 additions & 1 deletion core/src/main/java/io/jstach/rainbowgum/LogEncoder.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package io.jstach.rainbowgum;

import java.io.IOException;
import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
Expand Down
21 changes: 17 additions & 4 deletions core/src/main/java/io/jstach/rainbowgum/LogOutputRegistry.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,23 +74,36 @@ public Optional<LogOutput> output(String name) {
return Optional.ofNullable(outputs.get(name));
}

LogOutput provide(String name, LogProperties properties) throws IOException {
var o = output(name).orElse(null);
if (o != null) {
return o;
}
return output(URI.create(name + ":///"), name, properties);
}

@Override
public LogOutput output(URI uri, String name, LogProperties properties) throws IOException {
String scheme = uri.getScheme();
String path = uri.getPath();
OutputProvider customProvider;
if (scheme == null && path != null) {
@SuppressWarnings("resource")
FileOutputStream fos = new FileOutputStream(path);
return LogOutput.of(uri, fos.getChannel());
if (name.equals(LogAppender.FILE_APPENDER_NAME)) {
@SuppressWarnings("resource")
FileOutputStream fos = new FileOutputStream(path);
return LogOutput.of(uri, fos.getChannel());
}
else {
return provide(name, properties);
}
}
else if (NAMED_OUTPUT_SCHEME.equals(scheme)) {
String host = uri.getHost();
if (host != null) {
name = host;
}
String _name = name;
return output(name).orElseThrow(() -> new IOException("Output for name: " + _name + " not found."));
return output(_name).orElseThrow(() -> new IOException("Output for name: " + _name + " not found."));
}
else if (LogOutput.STDOUT_SCHEME.equals(scheme)) {
return LogOutput.ofStandardOut();
Expand Down
Loading

0 comments on commit a8e5c70

Please sign in to comment.