forked from awslabs/swage
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request awslabs#19 from jboynes/thread_metrics
Simplify thread local metrics
- Loading branch information
Showing
43 changed files
with
876 additions
and
973 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import software.amazon.swage.collection.TypedMap; | ||
import software.amazon.swage.metrics.ContextData; | ||
import software.amazon.swage.metrics.Metric; | ||
import software.amazon.swage.metrics.MetricContext; | ||
import software.amazon.swage.metrics.ThreadLocalMetrics; | ||
import software.amazon.swage.metrics.Unit; | ||
import software.amazon.swage.metrics.record.MetricRecorder; | ||
import software.amazon.swage.metrics.record.NullRecorder; | ||
import software.amazon.swage.threadcontext.ThreadContext; | ||
|
||
/** | ||
* Sample code that illustrates the different actors in the system. | ||
*/ | ||
public class Sample { | ||
private static final Metric NANO_TIME = Metric.define("Time"); | ||
private static final Metric CALL = Metric.define("Call"); | ||
|
||
public static void main(String[] args) { | ||
// Role 1: Set up the metric recording system. | ||
MetricRecorder recorder = new NullRecorder(); | ||
|
||
// Role 2: Set up the context in which measurements will be taken. | ||
TypedMap metadata = ContextData.withId("id").build(); | ||
try (MetricContext context = recorder.context(metadata)) { | ||
|
||
// Call a task that is aware of the MetricContext | ||
contextAware(context); | ||
|
||
// Options for calling code that is not aware of the metrics framework | ||
// First we add the MetricContext to the ThreadContext that will be used when | ||
// application code is called. Typically any other Thread-associated keys would | ||
// be added at the same time. | ||
ThreadContext threadContext = ThreadContext.emptyContext() | ||
.with(ThreadLocalMetrics.METRIC_CONTEXT, context); | ||
|
||
// Associating the MetricContext aroud a block of code. | ||
try (ThreadContext.CloseableContext ig = threadContext.open()) { | ||
applicationCode(); | ||
} | ||
|
||
// Or just using a wrapper if we're simply invoking a method. | ||
threadContext.wrap(Sample::applicationCode).run(); | ||
} | ||
} | ||
|
||
// Role 3: A task that emits metrics but is passed the MetricContext to use. | ||
private static void contextAware(MetricContext context) { | ||
context.record(NANO_TIME, System.nanoTime(), Unit.NONE); | ||
context.count(CALL); | ||
|
||
} | ||
// Role 3: A task that emits metrics, getting the context from the Thread. | ||
// The application code is not aware of metrics being collected. | ||
private static void applicationCode() { | ||
libraryCode(); | ||
} | ||
|
||
// But the library it uses emits metrics. | ||
private static void libraryCode() { | ||
MetricContext context = ThreadLocalMetrics.current(); | ||
context.record(NANO_TIME, System.nanoTime(), Unit.NONE); | ||
context.count(CALL); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
82 changes: 82 additions & 0 deletions
82
metrics-api/src/main/java/software/amazon/swage/metrics/MetricContext.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package software.amazon.swage.metrics; | ||
|
||
import java.time.Instant; | ||
|
||
import software.amazon.swage.collection.TypedMap; | ||
|
||
/** | ||
* The context in which a measurement is taken. A {MetricContext} contains the parameters of | ||
* the environment in which a measurement is taken. | ||
* In the physical world, these might define the effective time and place; | ||
* in a computer system, they might define the host, request, function, task or | ||
* other application-specific parameters. | ||
* <p/> | ||
* A {MetricContext} is the primary interface used to record measurements. | ||
*/ | ||
// TODO: provide a childContext() mechanism? | ||
public interface MetricContext extends AutoCloseable { | ||
/** | ||
* Returns the attributes and their values that identity the context in which measurements | ||
* are being taken. | ||
* | ||
* @return the Context attributes | ||
*/ | ||
TypedMap attributes(); | ||
|
||
/** | ||
* Record the value of a specific metric in this context, as gauged at a specific time. | ||
* | ||
* @param label the metric being recorded | ||
* @param value gauged value, with units. | ||
* @param unit type of the value, e.g. seconds, percent, etc. | ||
* @param time when the value was sampled | ||
*/ | ||
void record(Metric label, Number value, Unit unit, Instant time); | ||
|
||
/** | ||
* Record a measurement at the current time. | ||
* <p/> | ||
* Equivalent to calling record(metric, value, unit, Instant.now()) | ||
* | ||
* @param label the metric being recorded | ||
* @param value gauged value, with units. | ||
* @param unit type of the value, e.g. seconds, percent, etc. | ||
*/ | ||
default void record(Metric label, Number value, Unit unit) { | ||
record(label, value, unit, Instant.now()); | ||
} | ||
|
||
/** | ||
* Count the increase or decrease of a metric in the given context. | ||
* <p/> | ||
* Records a change in value of a metric in the scope of this context. This | ||
* is often used to record occurrences of an event, such as the number of times | ||
* a method is called, an error occurred, or the amount of data sent. | ||
* <p/> | ||
* Changes to the count are not timestamped as only the total value of all | ||
* counts for a metric have any meaning. If the individual change needs to | ||
* be tracked, it should be recorded as a gauged event. | ||
* | ||
* @param label the metric being recorded | ||
* @param delta the change in the value | ||
*/ | ||
void count(Metric label, long delta); | ||
|
||
/** | ||
* Count a single occurrence of a metric. | ||
* <p/> | ||
* Equivalent to calling count(label, 1). | ||
* | ||
* @param label the metric that occurred | ||
*/ | ||
default void count(Metric label) { | ||
count(label, 1L); | ||
} | ||
|
||
/** | ||
* Close this context, indicating that no more measurements will be taken. | ||
*/ | ||
@Override | ||
void close(); | ||
} | ||
|
Oops, something went wrong.