GelfEncoderBuilder.java
package io.jstach.rainbowgum.json.encoder;
import io.jstach.rainbowgum.LogProperties;
import io.jstach.rainbowgum.LogProperty;
/**
* Builder to create {@link io.jstach.rainbowgum.json.encoder.GelfEncoder }.
* Creates GELF Encoder.
* <table class="table">
* <caption><strong>Properties retrieved from LogProperties</strong></caption>
* <tr>
* <th>Property Pattern</th>
* <th>Type</th>
* <th>Required</th>
* <th>Default</th>
* <th>Description</th>
* </tr>
* <tr>
* <td><code>{@value PROPERTY_host }</code></td>
* <td><code>String</code></td>
* <td><code>true</code></td>
* <td><code>null</code></td>
* <td>Host field in GELF.</td>
* </tr>
* <tr>
* <td><code>{@value PROPERTY_headers }</code></td>
* <td><code>{@link LogProperties#mapOrNull(String) Map<String,String>}</code></td>
* <td><code>false</code></td>
* <td><code>null</code></td>
* <td>Additional headers that will be prefix with "_".</td>
* </tr>
* <tr>
* <td><code>{@value PROPERTY_prettyPrint }</code></td>
* <td><code>Boolean</code></td>
* <td><code>false</code></td>
* <td><code>null</code></td>
* <td><code>true</code> will pretty print the JSON, default is false.</td>
* </tr>
* <tr>
* <td><code>{@value PROPERTY_timeFractionalDigits }</code></td>
* <td><code>Integer</code></td>
* <td><code>false</code></td>
* <td><code>null</code></td>
* <td>Number of fractional second digits (0-9) the non-standard <code>_time</code> field is rendered with, default {@value GelfEncoder#DEFAULT_TIME_FRACTIONAL_DIGITS} (milliseconds). Values above 3 render genuine sub-millisecond precision (most JVMs' {@link java.time.Instant#now()} has real nanosecond resolution) but cannot be cached the way millisecond-or-coarser precision can, since it can legitimately differ between two events in the same millisecond.</td>
* </tr>
* <tr>
* <td><code>{@value PROPERTY_maxBufferSize }</code></td>
* <td><code>Integer</code></td>
* <td><code>false</code></td>
* <td><code>null</code></td>
* <td>Maximum buffer size - a soft ceiling checked between events, not a hard cap enforced on any single event (see {@link io.jstach.rainbowgum.LogEncoder.Buffer#isOversized()}). A negative value (the default) disables this entirely.</td>
* </tr>
* </table>
*/
public final class GelfEncoderBuilder implements io.jstach.rainbowgum.LogBuilder<GelfEncoderBuilder,io.jstach.rainbowgum.json.encoder.GelfEncoder> {
/**
* The properties to be retrieved from config will have
* this prefix.
*/
static final String PROPERTY_PREFIX = "logging.appender.{name}.encoder.gelf.";
/**
* <code>{@value #PROPERTY_host } = java.lang.String</code> Host field in GELF.
*/
static final String PROPERTY_host = PROPERTY_PREFIX + "host";
/**
* <code>{@value #PROPERTY_headers } = java.util.Map</code> Additional headers that will be prefix with "_".
*/
static final String PROPERTY_headers = PROPERTY_PREFIX + "headers";
/**
* <code>{@value #PROPERTY_prettyPrint } = java.lang.Boolean</code> <code>true</code> will pretty print the JSON, default is false.
*/
static final String PROPERTY_prettyPrint = PROPERTY_PREFIX + "prettyPrint";
/**
* <code>{@value #PROPERTY_timeFractionalDigits } = java.lang.Integer</code> Number of fractional second digits (0-9) the non-standard <code>_time</code> field is rendered with, default {@value GelfEncoder#DEFAULT_TIME_FRACTIONAL_DIGITS} (milliseconds). Values above 3 render genuine sub-millisecond precision (most JVMs' {@link java.time.Instant#now()} has real nanosecond resolution) but cannot be cached the way millisecond-or-coarser precision can, since it can legitimately differ between two events in the same millisecond.
*/
static final String PROPERTY_timeFractionalDigits = PROPERTY_PREFIX + "timeFractionalDigits";
/**
* <code>{@value #PROPERTY_maxBufferSize } = java.lang.Integer</code> Maximum buffer size - a soft ceiling checked between events, not a hard cap enforced on any single event (see {@link io.jstach.rainbowgum.LogEncoder.Buffer#isOversized()}). A negative value (the default) disables this entirely.
*/
static final String PROPERTY_maxBufferSize = PROPERTY_PREFIX + "maxBufferSize";
private final String propertyPrefix;
final String property_host;
final String property_headers;
final String property_prettyPrint;
final String property_timeFractionalDigits;
final String property_maxBufferSize;
private final java.lang.String name;
private java.lang.@org.jspecify.annotations.Nullable String host = null;
private java.util.@org.jspecify.annotations.Nullable Map<java.lang.String, java.lang.String> headers = null;
private java.lang.@org.jspecify.annotations.Nullable Boolean prettyPrint = null;
private java.lang.@org.jspecify.annotations.Nullable Integer timeFractionalDigits = null;
private java.lang.@org.jspecify.annotations.Nullable Integer maxBufferSize = null;
/**
* Create a builder for {@code io.jstach.rainbowgum.json.encoder.GelfEncoder }.
* @param name will fill <code>{name}</code> in <code>logging.appender.{name}.encoder.gelf.</code>. Property name prefix.
*/
public GelfEncoderBuilder(
java.lang.String name
) {
try {
java.util.Map<String,String> prefixParameters = java.util.Map.of(
"name", name
);
this.propertyPrefix = LogProperties.interpolateKey(PROPERTY_PREFIX, prefixParameters);
this.name = name;
property_host = LogProperties.interpolateKey(PROPERTY_host, prefixParameters);
property_headers = LogProperties.interpolateKey(PROPERTY_headers, prefixParameters);
property_prettyPrint = LogProperties.interpolateKey(PROPERTY_prettyPrint, prefixParameters);
property_timeFractionalDigits = LogProperties.interpolateKey(PROPERTY_timeFractionalDigits, prefixParameters);
property_maxBufferSize = LogProperties.interpolateKey(PROPERTY_maxBufferSize, prefixParameters);
}
catch (IllegalArgumentException e) {
throw LogProperty.ValidationException.of(this.getClass(), e);
}
}
/**
* Sets <strong>required</strong> host.
* Host field in GELF.
* Default is <code>null</code>.
* @param host <code>{@value #PROPERTY_host } = java.lang.String</code> Host field in GELF.
* @return this builder.
*/
public GelfEncoderBuilder host(java.lang.String host) {
this.host = host;
return this;
}
/**
* Sets headers.
* Additional headers that will be prefix with "_".
* Default is <code>null</code>.
* @param headers <code>{@value #PROPERTY_headers } = java.util.Map</code> Additional headers that will be prefix with "_".
* @return this builder.
*/
public GelfEncoderBuilder headers(java.util.@org.jspecify.annotations.Nullable Map<java.lang.String, java.lang.String> headers) {
this.headers = headers;
return this;
}
/**
* Sets prettyPrint.
* <code>true</code> will pretty print the JSON, default is false.
* Default is <code>null</code>.
* @param prettyPrint <code>{@value #PROPERTY_prettyPrint } = java.lang.Boolean</code> <code>true</code> will pretty print the JSON, default is false.
* @return this builder.
*/
public GelfEncoderBuilder prettyPrint(java.lang.@org.jspecify.annotations.Nullable Boolean prettyPrint) {
this.prettyPrint = prettyPrint;
return this;
}
/**
* Sets timeFractionalDigits.
* Number of fractional second digits (0-9) the non-standard <code>_time</code> field is rendered with, default {@value GelfEncoder#DEFAULT_TIME_FRACTIONAL_DIGITS} (milliseconds). Values above 3 render genuine sub-millisecond precision (most JVMs' {@link java.time.Instant#now()} has real nanosecond resolution) but cannot be cached the way millisecond-or-coarser precision can, since it can legitimately differ between two events in the same millisecond.
* Default is <code>null</code>.
* @param timeFractionalDigits <code>{@value #PROPERTY_timeFractionalDigits } = java.lang.Integer</code> Number of fractional second digits (0-9) the non-standard <code>_time</code> field is rendered with, default {@value GelfEncoder#DEFAULT_TIME_FRACTIONAL_DIGITS} (milliseconds). Values above 3 render genuine sub-millisecond precision (most JVMs' {@link java.time.Instant#now()} has real nanosecond resolution) but cannot be cached the way millisecond-or-coarser precision can, since it can legitimately differ between two events in the same millisecond.
* @return this builder.
*/
public GelfEncoderBuilder timeFractionalDigits(java.lang.@org.jspecify.annotations.Nullable Integer timeFractionalDigits) {
this.timeFractionalDigits = timeFractionalDigits;
return this;
}
/**
* Sets maxBufferSize.
* Maximum buffer size - a soft ceiling checked between events, not a hard cap enforced on any single event (see {@link io.jstach.rainbowgum.LogEncoder.Buffer#isOversized()}). A negative value (the default) disables this entirely.
* Default is <code>null</code>.
* @param maxBufferSize <code>{@value #PROPERTY_maxBufferSize } = java.lang.Integer</code> Maximum buffer size - a soft ceiling checked between events, not a hard cap enforced on any single event (see {@link io.jstach.rainbowgum.LogEncoder.Buffer#isOversized()}). A negative value (the default) disables this entirely.
* @return this builder.
*/
public GelfEncoderBuilder maxBufferSize(java.lang.@org.jspecify.annotations.Nullable Integer maxBufferSize) {
this.maxBufferSize = maxBufferSize;
return this;
}
/**
* Creates {@code io.jstach.rainbowgum.json.encoder.GelfEncoder } from this builder.
* @return {@code io.jstach.rainbowgum.json.encoder.GelfEncoder }.
*/
public io.jstach.rainbowgum.json.encoder.GelfEncoder build() {
try {
return io.jstach.rainbowgum.json.encoder.GelfEncoder.of(
this.name
, io.jstach.rainbowgum.LogProperty.require(property_host, this.host)
, this.headers
, this.prettyPrint
, this.timeFractionalDigits
, this.maxBufferSize
);
}
catch (IllegalArgumentException | LogProperty.PropertyMissingException e) {
throw LogProperty.ValidationException.of(this.getClass(), e);
}
}
@Override
public GelfEncoderBuilder fromProperties(LogProperties properties) {
var __v = LogProperty.Validator.of(this.getClass());
var _host = properties.forKey(property_host).ofString().or(this.host).validate(__v);
var _headers = properties.forKey(property_headers).ofMap().or(this.headers).validateIfError(__v);
var _prettyPrint = properties.forKey(property_prettyPrint).ofBoolean().or(this.prettyPrint).validateIfError(__v);
var _timeFractionalDigits = properties.forKey(property_timeFractionalDigits).ofInt().or(this.timeFractionalDigits).validateIfError(__v);
var _maxBufferSize = properties.forKey(property_maxBufferSize).ofInt().or(this.maxBufferSize).validateIfError(__v);
__v.validate();
this.host = _host.value();
this.headers = _headers.valueOrNull();
this.prettyPrint = _prettyPrint.valueOrNull();
this.timeFractionalDigits = _timeFractionalDigits.valueOrNull();
this.maxBufferSize = _maxBufferSize.valueOrNull();
return this;
}
/**
* The interpolated property prefix: {@value #PROPERTY_PREFIX}.
* @return resolved prefix which should end with a "<code>.</code>".
*/
@Override
public String propertyPrefix() {
return this.propertyPrefix;
}
}