com.launchdarkly.sdk.internal.events.Event Maven / Gradle / Ivy
package com.launchdarkly.sdk.internal.events;
import com.launchdarkly.sdk.EvaluationReason;
import com.launchdarkly.sdk.LDContext;
import com.launchdarkly.sdk.LDValue;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Base class for all analytics events that are generated by the client. Also defines all of its own subclasses.
*
* These types are not visible to applications; they are an implementation detail of the default event
* processor.
*/
public class Event {
private final long creationDate;
private final LDContext context;
/**
* Base event constructor.
*
* @param creationDate the timestamp in milliseconds
* @param context the context associated with the event
*/
public Event(long creationDate, LDContext context) {
this.creationDate = creationDate;
this.context = context;
}
/**
* The event timestamp.
*
* @return the timestamp in milliseconds
*/
public long getCreationDate() {
return creationDate;
}
/**
* The context associated with the event.
*
* @return the context object
*/
public LDContext getContext() {
return context;
}
/**
* Ratio used for sampling the event. The default sampling ratio is 1.
*
* Currently, sampling applies to feature, debug, and migration events.
*
* @return the sampling ratio
*/
public long getSamplingRatio() {
return 1;
}
/**
* A custom event created with one of the SDK's {@code track} methods.
*/
public static final class Custom extends Event {
private final String key;
private final LDValue data;
private final Double metricValue;
/**
* Constructs a custom event.
*
* @param timestamp the timestamp in milliseconds
* @param key the event key
* @param context the context associated with the event
* @param data custom data if any (null is the same as {@link LDValue#ofNull()})
* @param metricValue custom metric value if any
*/
public Custom(long timestamp, String key, LDContext context, LDValue data, Double metricValue) {
super(timestamp, context);
this.key = key;
this.data = LDValue.normalize(data);
this.metricValue = metricValue;
}
/**
* The custom event key.
*
* @return the event key
*/
public String getKey() {
return key;
}
/**
* The custom data associated with the event, if any.
*
* @return the event data (null is equivalent to {@link LDValue#ofNull()})
*/
public LDValue getData() {
return data;
}
/**
* The numeric metric value associated with the event, if any.
*
* @return the metric value or null
*/
public Double getMetricValue() {
return metricValue;
}
}
/**
* An event created with the SDK's {@code identify} method (or generated automatically at startup
* if it is a client-side SDK).
*/
public static final class Identify extends Event {
/**
* Constructs an identify event.
*
* @param timestamp the timestamp in milliseconds
* @param context the context associated with the event
*/
public Identify(long timestamp, LDContext context) {
super(timestamp, context);
}
}
/**
* An event created internally by the SDK to hold user data that may be referenced by multiple events.
*/
public static final class Index extends Event {
/**
* Constructs an index event.
*
* @param timestamp the timestamp in milliseconds
* @param context the context associated with the event
*/
public Index(long timestamp, LDContext context) {
super(timestamp, context);
}
}
/**
* An event generated by a feature flag evaluation.
*/
public static final class FeatureRequest extends Event {
private final String key;
private final int variation;
private final LDValue value;
private final LDValue defaultVal;
private final int version;
private final String prereqOf;
private final boolean trackEvents;
private final Long debugEventsUntilDate;
private final EvaluationReason reason;
private final boolean debug;
private final long samplingRatio;
private final boolean excludeFromSummaries;
/**
* Constructs a feature request event.
*
* @param timestamp the timestamp in milliseconds
* @param key the flag key
* @param context the context associated with the event
* @param version the flag version, or -1 if the flag was not found
* @param variation the result variation, or -1 if there was an error
* @param value the result value
* @param defaultVal the default value passed by the application
* @param reason the evaluation reason, if it is to be included in the event
* @param prereqOf if this flag was evaluated as a prerequisite, this is the key of the flag that referenced it
* @param trackEvents true if full event tracking is turned on for this flag
* @param debugEventsUntilDate if non-null, the time until which event debugging should be enabled
* @param debug true if this is a debugging event
* @param excludeFromSummaries true to exclude the event from summaries
* @param samplingRatio the sampling ratio for the event
*/
public FeatureRequest(long timestamp, String key, LDContext context, int version, int variation, LDValue value,
LDValue defaultVal, EvaluationReason reason, String prereqOf, boolean trackEvents,
Long debugEventsUntilDate, boolean debug, long samplingRatio, boolean excludeFromSummaries) {
super(timestamp, context);
this.key = key;
this.version = version;
this.variation = variation;
this.value = value;
this.defaultVal = defaultVal;
this.prereqOf = prereqOf;
this.trackEvents = trackEvents;
this.debugEventsUntilDate = debugEventsUntilDate;
this.reason = reason;
this.debug = debug;
this.excludeFromSummaries = excludeFromSummaries;
this.samplingRatio = samplingRatio;
}
/**
* Constructs a feature request event.
*
* This version of the constructor uses default values for the samplingRatio (1) and excludeFromSummaries (false).
*
* @param timestamp the timestamp in milliseconds
* @param key the flag key
* @param context the context associated with the event
* @param version the flag version, or -1 if the flag was not found
* @param variation the result variation, or -1 if there was an error
* @param value the result value
* @param defaultVal the default value passed by the application
* @param reason the evaluation reason, if it is to be included in the event
* @param prereqOf if this flag was evaluated as a prerequisite, this is the key of the flag that referenced it
* @param trackEvents true if full event tracking is turned on for this flag
* @param debugEventsUntilDate if non-null, the time until which event debugging should be enabled
* @param debug true if this is a debugging event
*/
public FeatureRequest(long timestamp, String key, LDContext context, int version, int variation, LDValue value,
LDValue defaultVal, EvaluationReason reason, String prereqOf, boolean trackEvents,
Long debugEventsUntilDate, boolean debug) {
this(timestamp, key, context, version, variation, value, defaultVal, reason, prereqOf, trackEvents,
debugEventsUntilDate, debug, 1, false);
}
/**
* The key of the feature flag that was evaluated.
*
* @return the flag key
*/
public String getKey() {
return key;
}
/**
* The index of the selected flag variation, or -1 if the application default value was used.
*
* @return zero-based index of the variation, or -1
*/
public int getVariation() {
return variation;
}
/**
* The value of the selected flag variation.
*
* @return the value
*/
public LDValue getValue() {
return value;
}
/**
* The application default value used in the evaluation.
*
* @return the application default
*/
public LDValue getDefaultVal() {
return defaultVal;
}
/**
* The version of the feature flag that was evaluated, or -1 if the flag was not found.
*
* @return the flag version or null
*/
public int getVersion() {
return version;
}
/**
* If this flag was evaluated as a prerequisite for another flag, the key of the other flag.
*
* @return a flag key or null
*/
public String getPrereqOf() {
return prereqOf;
}
/**
* True if full event tracking is enabled for this flag.
*
* @return true if full event tracking is on
*/
public boolean isTrackEvents() {
return trackEvents;
}
/**
* If debugging is enabled for this flag, the Unix millisecond time at which to stop debugging.
*
* @return a timestamp or null
*/
public Long getDebugEventsUntilDate() {
return debugEventsUntilDate;
}
/**
* The {@link EvaluationReason} for this evaluation, or null if the reason was not requested for this evaluation.
*
* @return a reason object or null
*/
public EvaluationReason getReason() {
return reason;
}
/**
* True if this event was generated due to debugging being enabled.
*
* @return true if this is a debug event
*/
public boolean isDebug() {
return debug;
}
public boolean isExcludeFromSummaries() {
return excludeFromSummaries;
}
@Override
public long getSamplingRatio() {
return samplingRatio;
}
/**
* Creates a debug event with the same properties as this event.
*
* @return a debug event
*/
public FeatureRequest toDebugEvent() {
return new FeatureRequest(getCreationDate(), getKey(), getContext(), getVersion(),
getVariation(), getValue(), getDefaultVal(), getReason(), getPrereqOf(),
false, null, true, samplingRatio, excludeFromSummaries);
}
}
/**
* An event generated by a migration operation.
*/
public static final class MigrationOp extends Event {
private final String featureKey;
private final int variation;
private final LDValue value;
private final LDValue defaultVal;
private final EvaluationReason reason;
private final long samplingRatio;
private final String operation;
private final int flagVersion;
private final ConsistencyMeasurement consistencyMeasurement;
private final LatencyMeasurement latencyMeasurement;
private final ErrorMeasurement errorMeasurement;
private final InvokedMeasurement invokedMeasurement;
/**
* Measurement used to indicate if the values in a read operation were consistent.
*/
public static final class ConsistencyMeasurement {
private final boolean consistent;
private final long samplingRatio;
/**
* Construct a new consistency measurement.
*
* @param consistent true if the result was consistent
* @param samplingRatio the sampling ratio for the consistency check
*/
public ConsistencyMeasurement(boolean consistent, long samplingRatio) {
this.consistent = consistent;
this.samplingRatio = samplingRatio;
}
/**
* Check if the operation was consistent.
*
* @return true if the operation was consistent
*/
public boolean isConsistent() {
return consistent;
}
/**
* Get the sampling ratio for the consistency check.
*
* @return the sampling ratio
*/
public long getSamplingRatio() {
return samplingRatio;
}
}
/**
* Latency measurement for a migration operation.
*/
public static final class LatencyMeasurement {
private final Long oldLatencyMs;
private final Long newLatencyMs;
/**
* Construct a latency measurement.
*
* @param oldLatency the old method latency, in milliseconds, or null if the old method was not executed
* @param newLatency the new method latency, in milliseconds, or null if the new method was not executed
*/
public LatencyMeasurement(@Nullable Long oldLatency, @Nullable Long newLatency) {
this.oldLatencyMs = oldLatency;
this.newLatencyMs = newLatency;
}
/**
* Get the old method execution latency in milliseconds.
*
* @return The old latency or null if the method was not invoked.
*/
public Long getOldLatencyMs() {
return oldLatencyMs;
}
/**
* Get the new method execution latency in milliseconds.
*
* @return The new latency or null if the method was not invoked.
*/
public Long getNewLatencyMs() {
return newLatencyMs;
}
/**
* Returns true if either of the durations are set.
*
* @return true if either of the durations are set
*/
public boolean hasMeasurement() {
return oldLatencyMs != null || newLatencyMs != null;
}
}
/**
* Error measurement for a migration operation.
*/
public static final class ErrorMeasurement {
private final boolean oldError;
private final boolean newError;
/**
* Construct an error measurement.
*
* @param oldError true if there was an error executing the old method
* @param newError true if there was an error executing the new method
*/
public ErrorMeasurement(boolean oldError, boolean newError) {
this.oldError = oldError;
this.newError = newError;
}
/**
* Check if there was an error executing the old method.
*
* @return true if there was an error executing the old method
*/
public boolean hasOldError() {
return oldError;
}
/**
* Check if there was an error executing the new method.
*
* @return true if there was an error executing the new method
*/
public boolean hasNewError() {
return newError;
}
/**
* Returns true if there are errors present for either of the origins.
*
* @return true if errors are present
*/
public boolean hasMeasurement() {
return oldError || newError;
}
}
/**
* Invoked measurement for a migration op.
*
* Indicates which origins/sources were executed while doing a migration operation.
*/
public static final class InvokedMeasurement {
private final boolean oldInvoked;
private final boolean newInvoked;
/**
* Construct a new invoked measurement.
*
* @param oldInvoked true if old was invoked
* @param newInvoked true if new was invoked
*/
public InvokedMeasurement(boolean oldInvoked, boolean newInvoked) {
this.oldInvoked = oldInvoked;
this.newInvoked = newInvoked;
}
/**
* Check if the old method was invoked.
*
* @return true if the old method was invoked
*/
public boolean wasOldInvoked() {
return oldInvoked;
}
/**
* Check if the new method was invoked.
*
* @return true if the new method was invoked
*/
public boolean wasNewInvoked() {
return newInvoked;
}
}
/**
* Construct a new migration operation event.
*
* @param timestamp the timestamp in milliseconds
* @param context the context associated with the event
* @param featureKey the flag key
* @param variation the result variation, or -1 if there was an error
* @param flagVersion the flag version, or -1 if the flag was not found
* @param value the result value
* @param defaultVal the default value passed by the application
* @param reason the evaluation reason, if it is to be included in the event
* @param samplingRatio the sampling ratio for this event
* @param operation the operation for the event
* @param invokedMeasurement measurement containing which origins were invoked
* @param consistencyMeasurement measurement containing results of a consistency check, or null if no check was done
* @param latencyMeasurement measurement containing the execution latencies of invoked methods, or null if no check
* was done
* @param errorMeasurement measurement reporting any errors, or null if no errors were encountered
*/
public MigrationOp(
long timestamp,
@NotNull LDContext context,
@NotNull String featureKey,
int variation,
int flagVersion,
@NotNull LDValue value,
@NotNull LDValue defaultVal,
@Nullable EvaluationReason reason, // For a server SDK this will not be null, but if it is ever used client side
// then likely this would be null unless evaluation reasons were requested.
long samplingRatio,
@NotNull String operation,
@NotNull InvokedMeasurement invokedMeasurement, // An invoked measurement is required.
@Nullable ConsistencyMeasurement consistencyMeasurement,
@Nullable LatencyMeasurement latencyMeasurement,
@Nullable ErrorMeasurement errorMeasurement
) {
super(timestamp, context);
this.featureKey = featureKey;
this.variation = variation;
this.flagVersion = flagVersion;
this.value = value;
this.defaultVal = defaultVal;
this.reason = reason;
this.samplingRatio = samplingRatio;
this.operation = operation;
this.consistencyMeasurement = consistencyMeasurement;
this.latencyMeasurement = latencyMeasurement;
this.errorMeasurement = errorMeasurement;
this.invokedMeasurement = invokedMeasurement;
}
/**
* The key of the feature flag that was evaluated.
*
* @return the flag key
*/
@NotNull
public String getFeatureKey() {
return featureKey;
}
/**
* The index of the selected flag variation, or -1 if the application default value was used.
*
* @return zero-based index of the variation, or -1
*/
public int getVariation() {
return variation;
}
/**
* The version of the feature flag that was evaluated, or -1 if the flag was not found.
*
* @return the flag version or -1
*/
public int getFlagVersion() {
return flagVersion;
}
/**
* The value of the selected flag variation.
*
* @return the value
*/
@NotNull
public LDValue getValue() {
return value;
}
/**
* The application default value used in the evaluation.
*
* @return the application default
*/
@NotNull
public LDValue getDefaultVal() {
return defaultVal;
}
/**
* The {@link EvaluationReason} for this evaluation, or null if the reason was not requested for this evaluation.
*
* @return a reason object or null
*/
@Nullable
public EvaluationReason getReason() {
return reason;
}
/**
* The {@link InvokedMeasurement} for this operation.
*
* @return the invoked measurement
*/
@NotNull
public InvokedMeasurement getInvokedMeasurement() {
return invokedMeasurement;
}
/**
* The {@link LatencyMeasurement} for this operation.
*
* @return the latency measurement or null
*/
@Nullable
public LatencyMeasurement getLatencyMeasurement() {
return latencyMeasurement;
}
/**
* The {@link ErrorMeasurement} for this operation.
*
* @return the error measurement or null
*/
@Nullable
public ErrorMeasurement getErrorMeasurement() {
return errorMeasurement;
}
/**
* Get the {@link ConsistencyMeasurement} for this operation.
*
* @return the consistency measurement or null
*/
@Nullable
public ConsistencyMeasurement getConsistencyMeasurement() {
return consistencyMeasurement;
}
/**
* Get the sampling ratio for this event.
*
* @return the sampling ratio
*/
@Override
public long getSamplingRatio() {
return samplingRatio;
}
/**
* Get the migration operation for this event.
*
* @return the migration operation
*/
public String getOperation() {
return operation;
}
}
}