Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move stats to metrics #226

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions api/src/main/java/openconsensus/metrics/CounterDouble.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
*
* void doWork() {
* // Your code here.
* defaultPoint.add(10);
* defaultTimeSeries.add(10);
* }
*
* }
Expand All @@ -66,7 +66,7 @@
*
* void doSomeWork() {
* // Your code here.
* inboundPoint.set(15);
* inboundTimeSeries.set(15);
* }
*
* }
Expand Down
4 changes: 2 additions & 2 deletions api/src/main/java/openconsensus/metrics/CounterLong.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
*
* void doWork() {
* // Your code here.
* defaultPoint.add(10);
* defaultTimeSeries.add(10);
* }
*
* }
Expand All @@ -67,7 +67,7 @@
*
* void doSomeWork() {
* // Your code here.
* inboundPoint.set(15);
* inboundTimeSeries.set(15);
* }
*
* }
Expand Down
4 changes: 2 additions & 2 deletions api/src/main/java/openconsensus/metrics/GaugeDouble.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
*
* void doWork() {
* // Your code here.
* defaultPoint.add(10);
* defaultTimeSeries.add(10);
* }
*
* }
Expand All @@ -67,7 +67,7 @@
*
* void doSomeWork() {
* // Your code here.
* inboundPoint.set(15);
* inboundTimeSeries.set(15);
* }
*
* }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

package openconsensus.stats;
package openconsensus.metrics;

import javax.annotation.concurrent.ThreadSafe;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

package openconsensus.stats;
package openconsensus.metrics;

import javax.annotation.concurrent.Immutable;

Expand Down
131 changes: 130 additions & 1 deletion api/src/main/java/openconsensus/metrics/Meter.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,142 @@

package openconsensus.metrics;

/** Entry point fot metrics API, this object allows to create new {@link MetricRegistry}. */
import java.util.List;
import openconsensus.tags.TagMap;
import openconsensus.trace.SpanContext;

/**
* Meter is a simple, interface that allows users to record measurements (metrics).
*
* <p>There are two ways to record measurements:
*
* <ul>
* <li>Record raw measurements, and defer defining the aggregation and the labels for the exported
* Metric. This should be used in libraries like gRPC to record measurements like
* "server_latency" or "received_bytes".
* <li>Record pre-defined aggregation data (or already aggregated data). This should be used to
* report cpu/memory usage, or simple metrics like "queue_length".
* </ul>
*
* <p>Example usage for raw measurement:
*
* <pre>{@code
* class MyClass {
* private static final Meter meter = Metrics.getMeter();
* private static final Measure cacheHit = meter.measureBuilder("cache_hit").build();
*
* Response serverHandler(Request request) {
* if (inCache(request)) {
* meter.record(Collections.singletonList(cacheHit.createMeasurement(1)));
* return fromCache(request);
* }
* ... // do other work
* }
*
* }
* }</pre>
*
* <p>Example usage for already aggregated metrics:
*
* <pre>{@code
* public final void exportGarbageCollectorMetrics {
* final CounterLong collectionMetric =
* meter
* .counterLongBuilder("collection")
* .setDescription("Time spent in a given JVM garbage collector in milliseconds.")
* .setUnit("ms")
* .setLabelKeys(Collections.singletonList(GC))
* .build();
* collectionMetric.setCallback(
* new Runnable() {
* &commat;Override
* public void run() {
* for (GarbageCollectorMXBean gc : ManagementFactory.getGarbageCollectorMXBeans()) {
* LabelValue gcName = LabelValue.create(gc.getName());
* collectionMetric
* .getOrCreateTimeSeries(Collections.singletonList(gcName))
* .set(gc.getCollectionTime());
* }
* }
* });
* }
* }</pre>
*
* <p>Example usage for simple pre-defined aggregation metrics:
*
* <pre>{@code
* class YourClass {
*
* private static final Meter meter = Metrics.getMeter();
* private static final MetricRegistry metricRegistry = meter.metricRegistryBuilder().build();
*
* List<LabelKey> labelKeys = Arrays.asList(LabelKey.create("Name", "desc"));
* List<LabelValue> labelValues = Arrays.asList(LabelValue.create("Inbound"));
*
* GaugeDouble gauge = metricRegistry.addDoubleGauge("queue_size",
* "Pending jobs", "1", labelKeys);
*
* // It is recommended to keep a reference of a TimeSeries.
* GaugeDouble.TimeSeries inboundTimeSeries = gauge.getOrCreateTimeSeries(labelValues);
*
* void doSomeWork() {
* // Your code here.
* inboundTimeSeries.add(15);
* }
*
* }
* }</pre>
*/
public interface Meter {

/**
* Returns a new builder for a {@code MetricRegistry}.
*
* @return a new builder for a {@code MetricRegistry}.
*/
// TODO: Consider to remove metric registry and move all methods in this class, or rename to a
// different name (maybe MetricsCollection). Also if an extra class is kept consider to move raw
// measurement API in it's own class as well.
MetricRegistry.Builder metricRegistryBuilder();

/**
* Returns a new builder for a {@code Measure}.
*
* @param name Name of measure, as a {@code String}. Should be a ASCII string with a length no
* greater than 255 characters.
* @return a new builder for a {@code Measure}.
* @since 0.1.0
*/
Measure.Builder measureBuilder(String name);

/**
* Records all given measurements, with the current {@link
* openconsensus.tags.Tagger#getCurrentTagMap}.
*
* @param measurements the list of {@code Measurement}s to record.
* @since 0.1.0
*/
void record(List<Measurement> measurements);

/**
* Records all given measurements, with an explicit {@link TagMap}.
*
* @param measurements the list of {@code Measurement}s to record.
* @param tags the tags associated with the measurements.
* @since 0.1.0
*/
void record(List<Measurement> measurements, TagMap tags);

/**
* Records all given measurements, with an explicit {@link TagMap}. These measurements are
* associated with the given {@code SpanContext}.
*
* @param measurements the list of {@code Measurement}s to record.
* @param tags the tags associated with the measurements.
* @param spanContext the {@code SpanContext} that identifies the {@code Span} for which the
* measurements are associated with.
* @since 0.1.0
*/
// TODO: Avoid tracing dependency and accept Attachments as in OpenCensus.
void record(List<Measurement> measurements, TagMap tags, SpanContext spanContext);
}
95 changes: 95 additions & 0 deletions api/src/main/java/openconsensus/metrics/NoopMetrics.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,13 @@

import java.util.List;
import java.util.Map;
import javax.annotation.concurrent.Immutable;
import javax.annotation.concurrent.ThreadSafe;
import openconsensus.internal.StringUtils;
import openconsensus.internal.Utils;
import openconsensus.resource.Resource;
import openconsensus.tags.TagMap;
import openconsensus.trace.SpanContext;

/**
* No-op implementations of metrics classes.
Expand All @@ -40,11 +45,42 @@ public static Meter newNoopMeter() {
}

private static final class NoopMeter implements Meter {
/* VisibleForTesting */ static final int NAME_MAX_LENGTH = 255;
private static final String ERROR_MESSAGE_INVALID_NAME =
"Name should be a ASCII string with a length no greater than "
+ NAME_MAX_LENGTH
+ " characters.";

@Override
public MetricRegistry.Builder metricRegistryBuilder() {
return new NoopMetricCollection.Builder();
}

@Override
public Measure.Builder measureBuilder(String name) {
Utils.checkArgument(
StringUtils.isPrintableString(name) && name.length() <= NAME_MAX_LENGTH,
ERROR_MESSAGE_INVALID_NAME);
return new NoopMeasure.NoopBuilder();
}

@Override
public void record(List<Measurement> measurements) {
Utils.checkNotNull(measurements, "measurements");
}

@Override
public void record(List<Measurement> measurements, TagMap tags) {
Utils.checkNotNull(measurements, "measurements");
Utils.checkNotNull(tags, "tags");
}

@Override
public void record(List<Measurement> measurements, TagMap tags, SpanContext spanContext) {
Utils.checkNotNull(tags, "tags");
Utils.checkNotNull(measurements, "measurements");
Utils.checkNotNull(spanContext, "spanContext");
}
}

private static final class NoopMetricCollection implements MetricRegistry {
Expand Down Expand Up @@ -425,4 +461,63 @@ public CounterLong build() {
}
}
}

@ThreadSafe
private static final class NoopMeasure implements Measure {
private final Type type;

private NoopMeasure(Type type) {
this.type = type;
}

@Override
public Measurement createDoubleMeasurement(double value) {
if (type != Type.DOUBLE) {
throw new UnsupportedOperationException("This type can only create double measurement");
}
Utils.checkArgument(value >= 0.0, "Unsupported negative values.");
return NoopMeasurement.INSTANCE;
}

@Override
public Measurement createLongMeasurement(long value) {
if (type != Type.LONG) {
throw new UnsupportedOperationException("This type can only create long measurement");
}
Utils.checkArgument(value >= 0, "Unsupported negative values.");
return NoopMeasurement.INSTANCE;
}

private static final class NoopBuilder implements Measure.Builder {
private Type type = Type.DOUBLE;

@Override
public Builder setDescription(String description) {
Utils.checkNotNull(description, "description");
return this;
}

@Override
public Builder setUnit(String unit) {
Utils.checkNotNull(unit, "unit");
return this;
}

@Override
public Builder setType(Type type) {
this.type = Utils.checkNotNull(type, "type");
return this;
}

@Override
public Measure build() {
return new NoopMeasure(type);
}
}
}

@Immutable
private static final class NoopMeasurement implements Measurement {
private static final Measurement INSTANCE = new NoopMeasurement();
}
}
Loading