ID | IEP-[NUMBER] |
Author | Alexander |
Sponsor |
|
Created | |
Status | DRAFT |
Motivation
Tracing provides information useful for debugging that both helps with regular, daily-basic system monitoring and with incidents analysis. Within the scope of Apache Ignite almost every process or sub-system could be traced including:
- Communication;
- Discovery;
- Exchange;
- Transactions;
- and many-many others
Each sub-system has specific motivation for tracing. For example, transaction tracing can highlight contention on some resource while taking a lock and thereby explain slow transaction.
Description
Seems that it makes sense to support an approach with extensibility and configurability of the trace/span handlers through common Ignite Service Provider Interfaces.
And cause Open Census is de-factor a standard (or at least one of the most popular solutions right now) it has sence to use it as build in tracing-handler implementation.
As an initial step following interfaces are proposed:
SpanManager
Manager for Span instances.
/**
* Manager for {@link Span} instances.
*/
public interface SpanManager {
/**
* Creates Span with given name.
*
* @param spanType Type of span to create.
*/
default Span create(@NotNull SpanType spanType) {
return create(spanType, (Span)null);
}
/**
* Creates Span given name and explicit parent.
*
* @param spanType Type of span to create.
* @param parentSpan Parent span.
* @return Created span.
*/
Span create(@NotNull SpanType spanType, @Nullable Span parentSpan);
/**
* Creates Span given name and explicit parent.
*
* @param spanType Type of span to create.
* @param serializedParentSpan Parent span as serialized bytes.
* @return Created span.
*/
Span create(@NotNull SpanType spanType, @Nullable byte[] serializedParentSpan);
/**
* Creates Span given name and explicit parent.
*
* @param spanType Type of span to create.
* @param parentSpan Parent span.
* @param lb Label.
* @return Created span.
*/
@NotNull Span create (
@NotNull SpanType spanType,
@Nullable Span parentSpan,
@Nullable String lb);
/**
* Serializes span to byte array to send context over network.
*
* @param span Span.
*/
byte[] serialize(@NotNull Span span);
}
Span
Logical piece of a trace that represents a single operation. Each unit work is called a Span in a trace. Spans include metadata about the work, including the time spent in the step (latency), status, time events, attributes, links.
/**
* Logical piece of a trace that represents a single operation.
* Each unit work is called a Span in a trace.
* Spans include metadata about the work, including the time spent in the step (latency),
* status, time events, attributes, links.
* You can use tracing to debug errors and latency issues in your applications.
*/
public interface Span {
/**
* Adds tag to span with {@code String} value.
*
* @param tagName Tag name.
* @param tagVal Tag value.
*/
Span addTag(String tagName, String tagVal);
/**
* Adds tag to span with {@code long} value.
*
* @param tagName Tag name.
* @param tagVal Tag value.
*/
Span addTag(String tagName, long tagVal);
/**
* Logs work to span.
*
* @param logDesc Log description.
*/
Span addLog(String logDesc);
/**
* Adds log to span with additional attributes.
*
* @param logDesc Log description.
* @param attrs Attributes.
*/
Span addLog(String logDesc, Map<String, String> attrs);
/**
* Explicitly set status for span.
*
* @param spanStatus Status.
*/
Span setStatus(SpanStatus spanStatus);
/**
* Ends span. This action sets default status if not set and mark the span as ready to be exported.
*/
Span end();
/**
* @return {@code true} if span has already ended.
*/
boolean isEnded();
/**
* @return Type of given span.
TracingConfigurationManager
Allows to configure tracing, read the configuration and restore it to the defaults.
/**
* Allows to configure tracing, read the configuration and restore it to the defaults.
*/
public interface TracingConfigurationManager {
/**
* Set new tracing configuration for the specific tracing coordinates (scope, label, etc.).
* If tracing configuration with specified coordinates already exists it'll be overrided,
* otherwise new one will be created.
*
* @param coordinates {@link TracingConfigurationCoordinates} Specific set of locators like {@link Scope} and label,
* that defines subset of traces and/or spans that'll use given configuration.
* @param parameters {@link TracingConfigurationParameters} e.g. sampling rate, set of included scopes etc.
* @throws IgniteException If failed to set tracing configuration.
*/
void set(@NotNull TracingConfigurationCoordinates coordinates,
@NotNull TracingConfigurationParameters parameters) throws IgniteException;
/**
* Get the most specific tracing parameters for the specified tracing coordinates (scope, label, etc.).
* The most specific means:
* <ul>
* <li>
* If there's tracing configuration that matches all tracing configuration attributes (scope and label) —
* it'll be returned.
* </li>
* <li>
* If there's no tracing configuration with specified label, or label wasn't specified —
* scope specific tracing configuration will be returned.
* </li>
* <li>
* If there's no tracing configuration with specified scope —
* default scope specific configuration will be returned.
* </li>
* </ul>
*
* @param coordinates {@link TracingConfigurationCoordinates} Specific set of locators like {@link Scope} and label
* that defines a subset of traces and/or spans that'll use given configuration.
* @return {@link TracingConfigurationParameters} instance.
* @throws IgniteException If failed to get tracing configuration.
*/
default @NotNull TracingConfigurationParameters get(
@NotNull TracingConfigurationCoordinates coordinates) throws IgniteException
{
switch (coordinates.scope()) {
case TX: {
return DEFAULT_TX_CONFIGURATION;
}
case EXCHANGE: {
return DEFAULT_EXCHANGE_CONFIGURATION;
}
default: {
return NOOP_CONFIGURATION;
}
}
}
/**
* List all pairs of tracing configuration coordinates and tracing configuration parameters
* or list all pairs of tracing configuration and parameters for the specific scope.
*
* @param scope Nullable scope of tracing configuration to be retrieved.
* If null - all configuration will be returned.
* @return The whole set of tracing configuration.
* @throws IgniteException If failed to get tracing configuration.
*/
@NotNull Map<TracingConfigurationCoordinates, TracingConfigurationParameters> getAll(
@Nullable Scope scope) throws IgniteException;
/**
* Reset tracing configuration for the specific tracing coordinates (scope, label, etc.) to default values.
* Please pay attention, that there's no default values for label specific coordinates,
* so such kinds of configurations will be removed.
*
* @param coordinates {@link TracingConfigurationCoordinates} specific set of locators like {@link Scope} and label
* that defines a subset of traces and/or spans that will be reset.
* @throws IgniteException If failed to reset tracing configuration.
*/
void reset(@NotNull TracingConfigurationCoordinates coordinates) throws IgniteException;
/**
* Reset tracing configuration for the specific scope, or all tracing configurations if scope not specified.
*
* @param scope {@link Scope} that defines a set of applicable tracing configurations.
* @throws IgniteException If failed to reset tracing configuration.
*/
void resetAll(@Nullable Scope scope) throws IgniteException;
}
Tracing
Tracing sub-system interface.
/**
*
*/
public interface Tracing extends SpanManager {
/**
* @return Helper to handle traceable messages.
*/
public TraceableMessagesHandler messages();
/**
* Returns the {@link TracingConfigurationManager} instance that allows to
* <ul>
* <li>Configure tracing parameters such as sampling rate for the specific tracing coordinates
* such as scope and label.</li>
* <li>Retrieve the most specific tracing parameters for the specified tracing coordinates (scope and label)</li>
* <li>Restore the tracing parameters for the specified tracing coordinates to the default.</li>
* <li>List all pairs of tracing configuration coordinates and tracing configuration parameters.</li>
* </ul>
* @return {@link TracingConfigurationManager} instance.
*/
public @NotNull TracingConfigurationManager configuration();
}
MTC
Despite the fact that it's not an interface it's also extremly important class that incapsulates logic of a thread-local span's storage.
public class MTC {
/**
* @return Span which corresponded to current thread or null if it doesn't not set.
*/
@NotNull public static Span span() {
return span.get();
}
/**
* Attach given span to current thread if it isn't null or attach empty span if it is null. Detach given span, close
* it and return previous span when {@link TraceSurroundings#close()} would be called.
*
* @param startSpan Span which should be added to current thread.
* @return {@link TraceSurroundings} for manage span life cycle.
*/
public static TraceSurroundings support(Span startSpan) {
...
}
/**
* Support initial span.
*
* @param startSpan Span which should be added to current thread.
*/
public static void supportInitial(Span startSpan) {
...
}
/**
* Attach given span to current thread if it isn't null or attach empty span if it is null.
*
* @param startSpan Span which should be added to current thread.
* @return {@link TraceSurroundings} for manage span life cycle.
*/
public static TraceSurroundings supportContinual(Span startSpan) {
...
}
}
Risks and Assumptions
// Describe project risks, such as API or binary compatibility issues, major protocol changes, etc.
Discussion Links
// Links to discussions on the devlist, if applicable.
Reference Links
// Links to various reference documents, if applicable.
Tickets
// Links or report with relevant JIRA tickets.