net.pincette.jes.elastic.Logging Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of pincette-jes-elastic Show documentation
Show all versions of pincette-jes-elastic Show documentation
Elasticsearch Utilities for pincette-jes
The newest version!
package net.pincette.jes.elastic;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.SEVERE;
import static net.pincette.jes.JsonFields.COMMAND;
import static net.pincette.jes.JsonFields.CORR;
import static net.pincette.jes.JsonFields.ID;
import static net.pincette.jes.JsonFields.STATUS_CODE;
import static net.pincette.jes.JsonFields.TIMESTAMP;
import static net.pincette.jes.JsonFields.TYPE;
import static net.pincette.jes.Util.getUsername;
import static net.pincette.json.JsonUtil.string;
import static net.pincette.json.Validate.hasErrors;
import static net.pincette.util.Or.tryWith;
import java.time.Instant;
import java.util.Optional;
import javax.json.JsonNumber;
import javax.json.JsonObject;
import net.pincette.jes.Aggregate;
import net.pincette.jes.elastic.ElasticCommonSchema.EventBuilder;
/**
* Elasticsearch logging utilities for JSON Event Sourcing.
*
* @author Werner Donné
* @since 1.0
*/
public class Logging {
private static final String ANONYMOUS = "anonymous";
private static final String COMMAND_ERROR = "COMMAND_ERROR";
private static final String ECS_COMMAND = "command";
private static final String EVENT = "event";
private static final String EXCEPTION = "exception";
private static final String MESSAGE = "message";
private static final String UNKNOWN = "unknown";
private Logging() {}
private static ElasticCommonSchema.Builder aggregateBuilder(
final Aggregate aggregate, final String serviceVersion) {
return new ElasticCommonSchema()
.withApp(aggregate.app())
.withEnvironment(aggregate.environment())
.withLogLevel(INFO)
.withService(fullType(aggregate))
.withServiceVersion(serviceVersion)
.builder();
}
/**
* Converts a command to an Elastic Common Schema message.
*
* @param command the command.
* @param aggregate the aggregate for which the command is meant.
* @param serviceVersion the version of the aggregate.
* @return The ECM message.
* @since 1.1
*/
public static JsonObject command(
final JsonObject command, final Aggregate aggregate, final String serviceVersion) {
final boolean errors = hasErrors(command);
return aggregateBuilder(aggregate, serviceVersion)
.addMessage(commandMessage(command))
.addTrace(trace(command))
.addUser(username(command))
.addTimestamp(timestamp(command))
.addEvent()
.addDataset(ECS_COMMAND)
.addOriginal(string(command, false))
.addAction(command.getString(COMMAND))
.addIf(
b -> errors,
b -> b.addCode(command.containsKey(EXCEPTION) ? SEVERE.getName() : COMMAND_ERROR))
.addIf(b -> errors, EventBuilder::addFailure)
.build()
.addIf(
b -> errors,
b ->
b.addError()
.addCode(commandCode(command))
.addMessage(errorMessage(command))
.build())
.build();
}
private static String commandCode(final JsonObject command) {
return Optional.ofNullable(command.getJsonNumber(STATUS_CODE))
.map(JsonNumber::longValue)
.orElse(0L)
.toString();
}
private static String commandMessage(final JsonObject command) {
return "Command " + commandSuffix(command);
}
private static String commandSuffix(final JsonObject json) {
return json.getString(COMMAND)
+ " for aggregate "
+ json.getString(ID)
+ " of type "
+ json.getString(TYPE);
}
private static String errorMessage(final JsonObject command) {
return tryWith(() -> command.getString(MESSAGE, null))
.or(() -> command.getString(EXCEPTION, null))
.or(() -> "Validation error")
.get()
.orElse("Unknown error");
}
/**
* Converts an event to an Elastic Common Schema message.
*
* @param event the event.
* @param aggregate the aggregate that produced the event.
* @param serviceVersion the version of the aggregate.
* @return The ECS message.
* @since 1.1
*/
public static JsonObject event(
final JsonObject event, final Aggregate aggregate, final String serviceVersion) {
return aggregateBuilder(aggregate, serviceVersion)
.addMessage(eventMessage(event))
.addTrace(trace(event))
.addUser(username(event))
.addTimestamp(timestamp(event))
.addEvent()
.addDataset(EVENT)
.addOriginal(string(event, false))
.addAction(event.getString(COMMAND))
.build()
.build();
}
private static String eventMessage(final JsonObject event) {
return "Event generated by command " + commandSuffix(event);
}
private static String fullType(final Aggregate aggregate) {
return aggregate.app() + "-" + aggregate.type();
}
private static Instant timestamp(final JsonObject json) {
return Optional.ofNullable(json.getJsonNumber(TIMESTAMP))
.map(JsonNumber::longValue)
.map(Instant::ofEpochMilli)
.orElseGet(Instant::now);
}
private static String trace(final JsonObject json) {
return json.getString(CORR, UNKNOWN);
}
private static String username(final JsonObject json) {
return getUsername(json).orElse(ANONYMOUS);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy